如何在使用Multi Datasource时在job-repo和step tasklet上设置TransactionManager

问题描述 投票:0回答:1

我有这样的Spring Batch应用程序。

从DB(产品)读取数据和保存到DB(newLagacy)。

<bean id="transactionManager_dataSource_newLagacy"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource_newLagacy" />
</bean>

<bean id="transactionManager_dataSource_product"
      class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource_product" />
</bean>


<bean id="jobRepositor_product" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="transactionManager" ref="transactionManager_dataSource_product" />
    <property name="dataSource" ref="dataSource_product" />
</bean>

<job id="job" job-repository="jobRepositor_product" incrementer="incrementer"xmlns="http://www.springframework.org/schema/batch">
    <step id="step">
        <tasklet transaction-manager="transactionManager_dataSource_newLagacy">
            <chunk reader="pagingItemReader" writer="mysqlItemWriter" commit-interval="1000" />
        </tasklet>
    </step>
</job>

和2个数据源。

    <bean id="dataSource_product" class="org.apache.tomcat.jdbc.pool.DataSource" primary="true">

       ......

    <bean id="dataSource_newLagacy" class="org.apache.tomcat.jdbc.pool.DataSource">
       ...... 

'dataSource_product'也用于保存Spring Batch Meta Tables(batch_ * tables)。

'dataSource_newLagacy'用于从数据库加载数据。

此设置没问题。

但是,当我将tasklet事务管理器更改为

“transactionManager dataSource产品”,出现了问题。

详细信息,写入项目后,编写批处理历史记录时。

2018:02:27 18:01:50.809 DEBUG --- [main] o.s.b.item.file.FlatFileItemWriter : Writing to flat file with 1000 items. 
2018:02:27 18:01:50.817 DEBUG --- [main] o.s.b.c.s.item.ChunkOrientedTasklet : Inputs not busy, ended: false 
2018:02:27 18:01:50.818 DEBUG --- [main] o.s.b.core.step.tasklet.TaskletStep : Applying contribution: [StepContribution: read=1000, written=1000, filtered=0, readSkips=0, writeSkips=0, processSkips=0, exitStatus=EXECUTING] 
2018:02:27 18:01:50.818 DEBUG --- [main] o.s.jdbc.datasource.DataSourceUtils : Returning JDBC Connection to DataSource 
2018:02:27 18:01:50.818 DEBUG --- [main] o.s.b.s.t.ResourcelessTransactionManager : Creating new transaction with name [org.springframework.batch.core.repository.support.SimpleJobRepository.updateExecutionContext]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
2018:02:27 18:01:50.819 DEBUG --- [main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL update 
2018:02:27 18:01:50.819 DEBUG --- [main] o.s.jdbc.core.JdbcTemplate : Executing prepared SQL statement [UPDATE BATCH_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?] 
2018:02:27 18:01:50.845 INFO  --- [main] o.s.j.support.SQLErrorCodesFactory : SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana] 
2018:02:27 18:01:50.845 DEBUG --- [main] o.s.j.support.SQLErrorCodesFactory : Looking up default SQLErrorCodes for DataSource [org.apache.tomcat.jdbc.pool.DataSource@37095ded] 
2018:02:27 18:01:50.847 WARN  --- [main] o.s.j.support.SQLErrorCodesFactory : Error while extracting database name - falling back to empty error codes 
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:342)
    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366)
    at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:212)
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134)
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:97)
    at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:655)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:876)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:937)
    at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.persistSerializedContext(JdbcExecutionContextDao.java:233)

我想知道为什么会这么说。

有一件事让我感到困惑的是

job-repo和step tasklet tx-manager之间的相同事务管理器使得truble(连接关闭)?

spring spring-batch multiple-databases
1个回答
0
投票

最后,我找到了原因。

DB,我称之为“产品”,将变量'wait_timeout'设置为'60'秒。当查询时间超过60秒时,连接已关闭,需要重新连接。但交易意味着没有其他联系。因此,当我没有设置任何交易时,它就可以了(即使连接已关闭,它也将重新连接)。但另一方面,它必须失败。因为它在交易中。

© www.soinside.com 2019 - 2024. All rights reserved.