Sahil lone opened SPR-13789 and commented
When we use Platform transaction management of Spring , the below example is how we use it.
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition(); transactionStatus = getTransactionManager().getTransaction(transactionDefinition); //do ur stuff here getTransactionManager().commit(transactionStatus);
If we will look above we have to explicitly commit the transaction or rollback it. In situations where we do not commit or rollback the transaction ; the transaction status is attached to thread and not removed on returning the thread to pool. As we already know only the owner function (function which started the transaction) can commit or rollback the transaction ; so when the transaction commit or rollback is missed , next time when the thread is again taken from pool and the thread is not recycled before reusing then the old transaction status is returned with thread . So any new transaction in case on TransactionDefinition.PROPAGATION_REQUIRED gives older transaction status and the current function calling the tx Manager doesn't become owner. So when the work is done and the function tries to commit or rollback , the transaction is niot actually commited. Because of this behaviour it leads to inconsistencies in data which developer is not aware.
This issue is because TransactionSynchronizationManager ie spring transaction management uses lot of thread local variable so the variable are not reset if transaction is not marked as completed.
There may be use cases where this behaviour maybe needed ie spaning transactions across thread reuse or across equests in case of serveet containers. But let me put this point that we can't be sure when thread variable will be garbage collected as it uses weak reference for thread local variables.
I have designed a Utility class for my project which takes care or these issues and ask for configuration o enable the utility and what to when transaction is missed.
Affects: 3.0.7
Issue Links: - #16383 Prevent corrupted ThreadLocals when mis-using triggerAfterCommit
0 votes, 5 watchers
Comment From: spring-projects-issues
Juergen Hoeller commented
This will indeed happen if you leave the transaction open. Point taken, we should take extra care to warn about such an outcome at least. We'll see what we can do for 4.3 there.
For a more defensive coding style, consider using TransactionTemplate
which accepts the actual resource interaction code in a callback and guarantees proper cleanup when its execute
call returns. This is a pretty nice option in particular with lambdas on Java 8.
The manual PlatformTransactionManager
interaction style that you are using above is a rather advanced feature (e.g. for third-party integrators) and not really recommended for common application components, exactly because of such potential clean-up issues.
Juergen
Comment From: spring-projects-issues
Sahil lone commented
@Juergen
Hoeller
Thanks for the reply.
We are currently working on the eProcurement which is needing to handle the large code base and also involves the integration with SAP and oracle and other ERP systems. Considering ur point of using TransactionTemplate or callbacks which we are using in application right now ; the overhead and the restriction on the usage of variable is a big problem. The problem arises as there is a addition of developers on regular basis and this much of code review is not possible on such a huge code base. We have faced this problem since the inception of project. Its a blocker in case where all the threads in pool are bound to missed transactions so the server needs to be restarted which is not possible for Prod environment. The Point being is there should be regular timely cleanup of transactions or the cleanup can be done by registering the dynamic filter which should be configurable.
The way we solved it is by using decorator design pattern where we extended your TransactionManager , TransactionStatus, and monitor each call to transactionManager and look for missed transaction based on the transactionTimeout set for our database and also included a filter based on configuration which will rollback the missed transactions.
If possible i can submit my code for review ; for it can be useful.
Comment From: spring-projects-issues
Sahil lone commented
We have also checked if thethread is asking for first transaction and if we get stale transaction from transactionMagere then we throw and exception of give a fresh transaction based on configuration for our QA servers and Prod servers respectively.
Spring can put property for transaction Manager which will always give a fresh transaction even if we have stale transaction.
Comment From: spring-projects-issues
Sahil lone commented
@Juergen
Hoeller
SIr can i know when will it be fixed. Or else I can help by committing my code for review if possible.
Comment From: spring-projects-issues
Santosh Tadikonda commented
@Sahil
lone, can you please share how you solved your issue if you have code snippets. Especially for the monitor and filter.