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;
}
source to share
No one has answered this question yet
Check out similar questions: