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