Springbatch失败|无法回滚JDBC事务

时间:2017-05-16 18:11:46

标签: java mysql spring spring-batch

我们在springbatch中运行了几个作业。我们今天早上重新启动了服务器,之后我们开始解决两个工作问题。 BATCH_STEP_EXECUTION表显示每个失败执行的以下退出消息:

org.springframework.transaction.TransactionSystemException: Could not roll back JDBC transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.
    at org.springframework.jdbc.datasource.DataSourceTransactionManager.doRollback(DataSourceTransactionManager.java:286)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:846)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:823)
    at org.springframework.transaction.support.TransactionTemplate.rollbackOnException(TransactionTemplate.java:162)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:135)
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:267)
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:253)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:141)
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
    at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:151)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:130)
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:301)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:134)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.ja

这似乎与应用程序正在进行的mysql连接有关,但是我不确定是什么导致这种情况,因为应用程序在重新启动之前运行正常。有没有人偶然发现过这个?

修改 (由日志中显示的消息引起)

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Connection.close() has already been called. Invalid operation in this state.

数据源

javax.sql.DataSource

连接池 在context.xml文件中使用以下格式进行配置:

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="webapps/appname" mapperContextRootRedirectEnabled="true" mapperDirectoryRedirectEnabled="true" path="/appname" reloadable="false" >

<Resource name="jdbc/springbatchmeta"
            auth="Container"
            type="javax.sql.DataSource"
            username="${jobmeta.username}"
            password="${jobmeta.password}"
            driverClassName="${mysql.driverClass}"
            url="${jobmeta.url}"
            initialSize="2"
            maxTotal="20"
            maxIdle="10"
            minIdle="2"/>

<Resource name="jdbc/firstjob"
            auth="Container"
            type="javax.sql.DataSource"
            username="${firstjob.username}"
            password="${firstjob.password}"
            driverClassName="${mysql.driverClass}"
            url="${firstjob.url}"
            initialSize="2"
            maxTotal="20"
            maxIdle="10"
            minIdle="2"/>

<Resource name="jdbc/secondjob"
            auth="Container"
            type="javax.sql.DataSource"
            username="${secondjob.username}"
            password="${secondjob.password}"
            driverClassName="${secondjob.driverClass}"
            url="${secondjob.url}"
            initialSize="2"
            maxTotal="20"
            maxIdle="10"
            minIdle="2"/>

</Context>

1 个答案:

答案 0 :(得分:-1)

此问题是由mysql中的wait-timeout选项设置为60秒引起的,因为我们运行的大多数作业都需要一分钟才能完成。