[jbossts-issues] [JBoss JIRA] (JBTM-2350) CDI Transactional interceptors are not thread safe. (previousUserTransactionAvailability)

Tomasz Krakowiak (JIRA) issues at jboss.org
Fri Mar 6 04:12:49 EST 2015


    [ https://issues.jboss.org/browse/JBTM-2350?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13046902#comment-13046902 ] 

Tomasz Krakowiak commented on JBTM-2350:
----------------------------------------

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!)



--
This message was sent by Atlassian JIRA
(v6.3.11#6341)


More information about the jbossts-issues mailing list