4
  • 我有一个由几个步骤组成的工作 - 其中一个步骤是激活处理 Pentaho 的 tasklet

  • 我将它需要的参数传递给 Pentaho,以便自行连接到数据库,它工作正常

  • 当 Pentaho 的处理时间很长时,我遇到的问题就开始了

  • Pentaho 成功完成并且激活它的 tasklet 中的代码完成正常,但是在包装它的作业机制中,当它尝试更新 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
    
  • 看起来作业开始时作业存储库收到的连接已被放弃,我试图了解是否有办法命令它获得新连接或给它一些保持活动命令

我尝试了以下解决方法

  • 更改作业侦听器中的步骤状态,以便作业完成 - 失败并出现相同的数据库错误

  • 将此异常标记为可以跳过 - 失败并出现相同的数据库错误

     <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(DataSource)

这个

    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)是连接持有者持有一个关闭的连接,但这里的代码不检查连接是否打开;它只检查连接是否不为空,如果它是一些弱引用,也许这里就足够了——但在这个用例中,它只是继续关闭连接而不是请求新连接。

4

1 回答 1

3

将此添加到 tasklet 定义中

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

由于 Tasklet 正在进行外部处理并且不需要 Spring Batch 事务,因此它需要告诉 Spring Batch 不要为此 Tasklet 打开事务。

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

于 2014-06-18T16:08:32.727 回答