[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