[jboss-jira] [JBoss JIRA] (WFLY-4384) ContextService (JSR236): transactional context always suspended

Tobias Rötschke (JIRA) issues at jboss.org
Tue Mar 3 03:44:49 EST 2015


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

Tobias Rötschke edited comment on WFLY-4384 at 3/3/15 3:44 AM:
---------------------------------------------------------------

Please let me eloborate on Maxim's question. What we are trying to do, is to execute code in concurrent threads, but within the same transaction. Our guiding example is Gupta's "Java EE 7 Essentials", chapter 10. I understand that invoking the contextual object -- not creating it -- is influenced by the USE_TRANSACTION_OF_EXECUTION_THREAD property value.  That results from the beforeProxyMethod() of the TransactionSetupProviderImpl class. However, the code seemingly expects that the thread, where the proxy method is executed in, is already attached to the transaction of the invoking thread. 

This turns out not be the case in our setting. As you point out, ManagedExecutorService runs in an internal thread outside a transaction. So we used Executors.newFixedThreadPool() instead as in Gupta's example. We passed the default ManagedThreadFactory to this method. We supplied the contextual object with the TransactionManager injected to the class inside the invoking thread. We verified that the contextual object is invoked directly from the invoking thread. However, TransactionManager.getTransaction() yielded null inside the thread of the contextual object. 

Question is: What are we supposed to do in order to attach the thread of the contextual object to the transaction of the invoking thread in the first place so that TransactionSetupProviderImpl.beforeProxy does what it is meant to do? Unfortunately, the javadoc example you cited did not help to explain that to us. 

Whether or not this issue is a bug depends on who is responsible for attaching the invoked thread to the transaction of the invoker. In my opinion the JSR-236-implementation is, otherwise USE_TRANSACTION_OF_EXECUTION_THREAD  wouldn't make much sense to me. If the application has to take care of it, what is the point of this execution property? We might still be wrong in the way we use that implementation though.



was (Author: tobias.roetschke):
Please let me eloborate on Maxim's question. What we are trying to do, is to execute code in concurrent threads, but within the same transaction. Our guiding example is Gupta's "Java EE 7 Essentials", chapter 10. I understand that invoking the contextual object -- not creating it -- is influenced by the USE_TRANSACTION_OF_EXECUTION_THREAD property value.  That results from the beforeProxyMethod() of the TransactionSetupProviderImpl class. However, the code seemingly expects that the thread, where the proxy method is executed in, is already attached to the transaction of the invoking thread. 

This turns out not be the case in our setting. As you point out, ManagedExecutorService runs in an internal thread outside a transaction. So we used Executors.newFixedThreadPool() instead as in Gupta's example. We passed the default ManagedThreadFactory to this method. We supplied the contextual object with the TransactionManager injected to the class inside the invoking thread. We verified that the contextual object is invoked directly from the invoking thread. However, TransactionManager.getTransaction() yielded null inside the thread of the contextual object. 

Question is: What are we supposed to do in order to attach the thread of the contextual object to the transaction of the invoking thread in the first place so that TransactionSetupProviderImpl.beforeProxy does what it is meant to do? Unfortunately, the javadoc example you cited did not help to explain that to us.

> ContextService (JSR236): transactional context always suspended
> ---------------------------------------------------------------
>
>                 Key: WFLY-4384
>                 URL: https://issues.jboss.org/browse/WFLY-4384
>             Project: WildFly
>          Issue Type: Bug
>          Components: EE
>    Affects Versions: 8.2.0.Final, 9.0.0.Alpha1
>            Reporter: Maxim Frolov
>            Assignee: Eduardo Martins
>            Priority: Critical
>
> According to §3.3.5 of JSR-236 specification: 
> ??By using an execution property when creating the contextual proxy object, application components can choose to not suspend the transactional context on the thread ...??
> Given the following EJB and Task:
> {code:java}
> @WebService(serviceName = "Jsr236WebService")
> @Stateless
> public class Jsr236WebService {
>     @Inject Jsr236ManagedTask jsr236ManagedTask;
>     @Resource ManagedExecutorService executor;
>     @Resource ContextService contextService;
>  
>     @WebMethod(operationName = "hello")
>     public String hello(@WebParam(name = "name") String txt) {
>         Map<String, String> execProps = new HashMap<>();
>         execProps.put(ManagedTask.TRANSACTION, ManagedTask.USE_TRANSACTION_OF_EXECUTION_THREAD);
>         Future<String> future = executor.submit(
>                 contextService.createContextualProxy(jsr236ManagedTask, execProps, Callable.class));
>         try {
>             return future.get();
>         } catch (InterruptedException | ExecutionException e) {
>             throw new RuntimeException(e);
>         }
>     }
> }
> {code}
> {code:java}
> @Dependent
> @Transactional(Transactional.TxType.MANDATORY)
> public class Jsr236ManagedTask implements Callable<String>, ManagedTask {
>     @Override
>     public String call() {
>         return "called";
>     }
>     @Override
>     public Map<String, String> getExecutionProperties() {
>        Map<String, String> execProps = new HashMap<>();
>         execProps.put(ManagedTask.TRANSACTION, ManagedTask.USE_TRANSACTION_OF_EXECUTION_THREAD);
>         return execProps;
>     }
> }
> {code}
> When the {{call()}} Method of the task is called the following exception occurs:
> {noformat}
> javax.transaction.TransactionalException: ARJUNA016110: Transaction is required for invocation
> {noformat}
> See maven test project [https://github.com/wrungel/bugs/tree/master/jsr236-test] on GitHub.



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



More information about the jboss-jira mailing list