Spring transaction - cannot release transaction after error

I am using Spring-tx-4.0.9 in a multithreaded application and have an issue with a "stopped" transaction after the thread has been killed by OutOfMemory.

Each thread requests PlatformTransactionManager

(implementation org.springframework.jdbc.datasource.DataSourceTransactionManager

) to receive a transaction through the TransactionTemplate

SOFTWARE REQUIRED. This template has a timeout. The state of the transaction is managed by the application, and eventually the work is done, then the threads are called. This reverts the transaction back to PlatformTransactionManager

and releases the DB connection almost every time (in DB the session for that connection is mostly released)

But if the thread is disabled by OutOfMemory, then the underlying transaction is returned to the internal transaction pool, and another thread can receive this "broken" transaction. This transaction has a first-time timeout and cannot be reset even if a new thread calls TM to receive the transaction from new TransactionTemplate

. Therefore, after this timeout expires, each transaction request issues TransactionTimedOutException

.

Only available methods PlatformTransactionManager

: getTransaction

, commit

and rollback

. The method getTransaction

can return a new or previous transaction. From the returned instance, TransactionStatus

I can detect a new or suspended transaction, but I cannot release it.

The method rollback

sets a flag isRollbackOnly

, but the transaction is still not released, but getTransaction

returns stalled. If I then call commit

as the JavaDoc recommended, then nothing has changed and the transaction is still hung.

If I use propagation REQUIRES_NEW

then the "broken" transaction is suspended, which solves the problem TransactionTimedOutException

, but the old transaction still hangs and holds the DB connection (unwanted state).

Is there a way how to properly release a broken transaction (rollback and release of the connection)?

EDIT- Current code for getting 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;
  }

      

+3


source to share





All Articles