]
Tomasz Krakowiak edited comment on JBTM-2350 at 3/6/15 4:12 AM:
----------------------------------------------------------------
Use case:
We are queuing some messages on JMS. We use our own JMS consumers which run in BMT.
However submitting messages occurs in CMT. Both submitting and processing message use some
DAO beans which use transactional annotations.
I encountered this issue on production. I fixed it and hacked in my SNAPSHOT into wildfly
- it resolved the issue.
I would write unit test for it, but I haven't figured out how to run narayana
arquillian tests (-Parq). It requires some some additional parameters and configured
environment i guess.
was (Author: niematojaktomasz):
Use case:
We are queuing some messages on JMS. We use our own JMS consumers which run in BMT.
However submitting messages occurs in CMT. Both submitting and processing message use some
DAO beans which use transactional annotations.
I encountered this issue on production. I fixed it by hacking in SNAPSHOT into wildfly -
it resolved the issue.
I would write unit test for it, but I haven't figured out how to run narayana
arquillian tests (-Parq). It requires some some additional parameters and configured
environment i guess.
CDI Transactional interceptors are not thread safe.
(previousUserTransactionAvailability)
-----------------------------------------------------------------------------------------
Key: JBTM-2350
URL:
https://issues.jboss.org/browse/JBTM-2350
Project: JBoss Transaction Manager
Issue Type: Bug
Components: JTA
Affects Versions: 5.0.0, 5.0.1, 5.0.2, 5.0.3, 5.0.4
Environment: Wildfly 8.1.0, Wildfly 8.2.0, linux, OS X
Reporter: Tomasz Krakowiak
Assignee: Tom Jenkinson
The problem is with availability of `UserTransaction`.
Availability of UserTransaction is stored in `ServerVMClientUserTransaction.isAvailables`
which is `ThreadLocal<Boolean>`.
`TransactionalInterceptorRequired` when intercepting call, stores thread local value of
`isAvailables` in `TransactionalInterceptorBase.previousUserTransactionAvailability` field
of interceptor - which is of type boolean(not thread local).
Here's a story:
We have a bean (beanA) with single method annotated transactional
(beanA.transactional()).
This method is being called from two threads, where:
- Thread 1 is participating in BMT, therefore it's
ServerVMClientUserTransaction.isAvailables value is true.
- Thread 2 is participating in CMT, therefore it's
ServerVMClientUserTransaction.isAvailables value is false.
Both threads call beanA.transactional() at the same time.
What may happen:
1. Thread 1 - enters method beanA.transactional.
Interceptor sets previousUserTransactionAvailability to true.
2. Thread 2 - enters method beanB.transactional.
Interceptor sets previousUserTransactionAvailability to false.
3. Thread 1 - exits method beanA.transactional
Interceptor restores thread local value of `isAvailables` to false (leaked value
from thread 2!)