[jboss-jira] [JBoss JIRA] Assigned: (JBRULES-2937) JtaTransactionManager should use setRollbackOnly instead of rollback for non-local transactions

Mark Proctor (JIRA) jira-events at lists.jboss.org
Tue May 17 20:18:01 EDT 2011


     [ https://issues.jboss.org/browse/JBRULES-2937?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Mark Proctor reassigned JBRULES-2937:
-------------------------------------

    Assignee: Kris Verlaenen  (was: Mark Proctor)


> JtaTransactionManager should use setRollbackOnly instead of rollback for non-local transactions
> -----------------------------------------------------------------------------------------------
>
>                 Key: JBRULES-2937
>                 URL: https://issues.jboss.org/browse/JBRULES-2937
>             Project: Drools
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>          Components: drools-core (flow)
>    Affects Versions: 5.2.0.M1
>         Environment: WinXP, Oracle Java 1.6.0_20, 32bit, JBoss AS 6.0.0.Final, jBPM 5.0.0
>            Reporter: Vlastimil Menčík
>            Assignee: Kris Verlaenen
>             Fix For: 5.2.0.CR1
>
>
> This problem concerns the {{drools-persistence-jpa}} module and its {{org.drools.persistence.jta.JtaTransactionManager}}.
> The {{JtaTransactionManager}} has a notion of local transactions. These are the JTA transactions that it itself started using [UserTransaction.begin()|http://download.oracle.com/javaee/6/api/javax/transaction/UserTransaction.html#begin%28%29].
> If a JTA transaction is already active when {{JtaTransactionManager.begin()}} is called, then the execution continues in this JTA transaction and a new one is not started. Let's call such JTA transaction non-local.
> The problem is that {{JtaTransactionManager.rollback()}} treats local and non-local JTA transactions the same way and calls [UserTransaction.rollback()|http://download.oracle.com/javaee/6/api/javax/transaction/UserTransaction.html#rollback%28%29] in both cases. In case of a non-local transaction is this behaviour IMHO wrong, because the rollback should be a responsibility of the same client that started the JTA transaction.
> Imagine the following situation (jBPM process execution):
> {code}
> StatefulKnowledgeSession session = ...
> UserTransaction ut = ...
> ut.begin();
> try {
>     session.startProcess("my.process"); // the process execution may cause an exception (most likely in some WorkItemHandler)
>     ut.commit();
> } catch (Exception e) {
>     ut.rollback(); // now this throws an IllegalStateException, because JtaTransactionManager already rolled back the transaction
> }
> {code}
> There is of course a workaround: the client code has to check [status|http://download.oracle.com/javaee/6/api/javax/transaction/UserTransaction.html#getStatus%28%29] of the JTA transaction and must not call {{rollback()}}, if the transaction was already rolled back by the {{JtaTransactionManager}}.
> IMHO the relevant JtaTransactionManager code should call [UserTransaction.setRollbackOnly|http://download.oracle.com/javaee/6/api/javax/transaction/UserTransaction.html#setRollbackOnly%28%29] for non-local transactions:
> {code}
> public void rollback() {
>     boolean wasLocal = localTransaction; // localTransaction is a private boolean field of JtaTransactionManager already present in current implementation
>     localTransaction = false;
>     try {
>         wasLocal ? this.ut.rollback() : this.ut.setRollbackOnly();
>     } catch ( Exception e ) {
>         logger.warn( "Unable to rollback transaction", e);
>         throw new RuntimeException( "Unable to rollback transaction", e );
>     }
> } 
> {code}

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

       



More information about the jboss-jira mailing list