Spring Transaction - 错误后无法释放Transaction

时间:2017-05-30 10:59:04

标签: java spring transactions spring-transactions transactionmanager

我在多线程应用程序中使用Spring-tx-4.0.9,并且在线程被OutOfMemory杀死后出现“停滞”事务的问题。

每个帖子都要求PlatformTransactionManager(实现org.springframework.jdbc.datasource.DataSourceTransactionManager)通过TransactionTemplate进行交易。传播是必需的。此模板具有超时设置。事务状态由应用程序管理,毕竟工作完成,然后线程调用commit。这会将事务返回到PlatformTransactionManager,并且几乎每次都释放与DB的连接(在DB中,此连接的会话主要是释放)

但是如果线程被OutOfMemory杀死,那么底层事务将返回到内部事务池,而另一个线程可以获取此“已损坏”事务。此事务具有从第一次设置的超时,即使新线程调用TM以获得与new TransactionTemplate的事务,也无法重置。因此,在此超时到期后,每个事务请求都会抛出TransactionTimedOutException

PlatformTransactionManager上的可用方法为getTransactioncommitrollback。 方法getTransaction可以返回新的或以前的事务。从返回的TransactionStatus实例,我能够检测到新的或停滞的事务,但我无法释放它。

方法rollback设置标记isRollbackOnly,但事务仍未释放,getTransaction返回停止。如果我按照JavaDoc的建议调用commit,那么没有任何改变,交易仍然被挂起。

如果我使用传播REQUIRES_NEW,那么“已损坏”事务将被暂停,这会解决TransactionTimedOutException的问题,但旧事务仍然被挂起并保持与数据库的连接(不需要的状态)

有没有办法,如何正确释放损坏的事务(回滚和释放连接)?

EDIT-获取TransactionalStatus的当前代码

public TransactionStatus beginTransaction() {
    // transaction begin
    logger.debug("Create new transaction.");
    TransactionTemplate template = new TransactionTemplate(transactionManager);
    template.setTimeout(txConnectionTimeout);

    TransactionStatus txStatus = transactionManager.getTransaction(template);
    logger.debug(
        "Transaction created. TransactionStatus: isCompleted=" + txStatus.isCompleted() + ", isNewTransaction=" +
        txStatus.isNewTransaction());

    return txStatus;
  }

0 个答案:

没有答案
相关问题