Spring Batch - 在外部进程中完成处理时关闭

时间:2014-06-17 14:31:57

标签: java spring-batch database-metadata

  • 我的工作由几个步骤构成 - 其中一个步骤是激活处理Pentaho的tasklet
  • 我向Pentaho传递了它所需的参数,以便连接到它自己的数据库并且工作正常
  • 当Pentaho的处理时间很长时,我的问题就开始了
  • Pentaho成功完成并且激活它的tasklet中的代码完成了OK,但是在包装它的作业机制中,当它尝试更新db中的作业执行表时会出现错误,因为它具有连接已经关闭

    o.s.j.s.SQLErrorCodesFactory: Error while extracting database product 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:296)
        at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:320)
        at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:214)
        at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:141)
        at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:104)
        at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:812)
        at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:868)
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.persistSerializedContext(JdbcExecutionContextDao.java:230)
        at org.springframework.batch.core.repository.dao.JdbcExecutionContextDao.updateExecutionContext(JdbcExecutionContextDao.java:159)
        at org.springframework.batch.core.repository.support.SimpleJobRepository.updateExecutionContext(SimpleJobRepository.java:203)
    ...
    14:21:37.143 UTC [ERROR] jobScheduler_Worker-2 T:b U: o.s.t.i.TransactionInterceptor: Application exception overridden by rollback exception
    org.springframework.dao.RecoverableDataAccessException: PreparedStatementCallback; SQL [UPDATE BAT_STEP_EXECUTION_CONTEXT SET SHORT_CONTEXT = ?, SERIALIZED_CONTEXT = ? WHERE STEP_EXECUTION_ID = ?]; Communications link failure
    
  • 看起来作业存储库在作业启动时收到的连接被放弃了,我试图了解是否有办法订购它获得新连接或给它一些保持活动命令

我尝试了以下变通办法

  • 更改作业侦听器中的步骤状态,以便作业完成 - 失败且出现相同的DB错误
  • 将此异常标记为可以跳过 - 以相同的DB错误失败

    <batch:no-rollback-exception-classes>
      <batch:include class="com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException" />
      <batch:include class="org.springframework.jdbc.support.MetaDataAccessException" />
    </batch:no-rollback-exception-classes>
    

我有什么想法可以解决这个问题吗?

我可以配置一个将从Pentaho步骤后面的步骤重启作业的作业监听器吗?

其他信息 我认为这个问题在这里 - 的 org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(数据源)

    ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);

认为连接有效

所以我想解决方法是调用 org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(Object)

问题是我如何才能将数据源对象传递给此方法

我会尝试查询 的 org.springframework.transaction.support.TransactionSynchronizationManager.getResourceMap() 并看看它在哪里得到我

更新 没有运气 - 获取资源图给我的存储库我只使用的不是数据源 还在挖......

另一次更新

我正在调试这个过程,似乎问题确实是 org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSource)连接持有者是一个关闭的连接但是这里的代码不会检查连接是否打开,它会检查连接是否为空,如果它是一些弱引用,也许它就足够了 - 但是在这个用例中它只是用闭合连接取代而不是请求新的

1 个答案:

答案 0 :(得分:0)

将其添加到tasklet定义

<batch:transaction-attributes propagation="NEVER" />

由于Tasklet正在进行外部处理,并且不需要弹出批处理事务,因此需要告诉spring批处理不要为此tasklet打开事务。

http://www.javabeat.net/transaction-management-in-spring-batch-components/ http://forum.spring.io/forum/spring-projects/batch/91158-legacy-integration-tasklet-transaction