[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:53:49 EST 2015


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

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

[~mmusgrov] Thread local wouldn't work correctly if interceptor would be called recursively.

> 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 `beanA.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