deltaspike-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From strub...@apache.org
Subject git commit: DELTASPIKE-507 fallback to TransactionSynchronisationRegistry
Date Tue, 21 Jan 2014 16:56:55 GMT
Updated Branches:
  refs/heads/master e5432a016 -> a34a8ed3e


DELTASPIKE-507 fallback to TransactionSynchronisationRegistry

txs to sstrobl for the patch
also big txs to dblevins for the hint to this hidden gem.


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/a34a8ed3
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/a34a8ed3
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/a34a8ed3

Branch: refs/heads/master
Commit: a34a8ed3eeb5f8e95ee9b4432ece9d25ad266525
Parents: e5432a0
Author: Mark Struberg <struberg@apache.org>
Authored: Tue Jan 21 17:55:50 2014 +0100
Committer: Mark Struberg <struberg@apache.org>
Committed: Tue Jan 21 17:55:50 2014 +0100

----------------------------------------------------------------------
 .../BeanManagedUserTransactionStrategy.java     | 98 +++++++++++++++++---
 1 file changed, 85 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/a34a8ed3/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/BeanManagedUserTransactionStrategy.java
----------------------------------------------------------------------
diff --git a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/BeanManagedUserTransactionStrategy.java
b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/BeanManagedUserTransactionStrategy.java
index 556b6d8..660bf0f 100644
--- a/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/BeanManagedUserTransactionStrategy.java
+++ b/deltaspike/modules/jpa/impl/src/main/java/org/apache/deltaspike/jpa/impl/transaction/BeanManagedUserTransactionStrategy.java
@@ -31,6 +31,7 @@ import javax.persistence.EntityManager;
 import javax.persistence.EntityTransaction;
 import javax.transaction.Status;
 import javax.transaction.SystemException;
+import javax.transaction.TransactionSynchronizationRegistry;
 import javax.transaction.UserTransaction;
 import java.lang.annotation.Annotation;
 import java.util.logging.Level;
@@ -49,6 +50,7 @@ import java.util.logging.Logger;
 public class BeanManagedUserTransactionStrategy extends ResourceLocalTransactionStrategy
 {
     protected static final String USER_TRANSACTION_JNDI_NAME = "java:comp/UserTransaction";
+    protected static final String TRANSACTION_SYNC_REGISTRY_JNDI_NAME = "java:comp/TransactionSynchronizationRegistry";
 
     private static final long serialVersionUID = -2432802805095533499L;
 
@@ -80,7 +82,17 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
         try
         {
             UserTransaction userTransaction = resolveUserTransaction();
-            userTransaction.setTransactionTimeout(transactionTimeout);
+
+            if (userTransaction == null)
+            {
+                // if there is a CMT EJB call active, then we do not set any timeout
+                return;
+            }
+
+            if (userTransaction.getStatus() != Status.STATUS_ACTIVE)
+            {
+                userTransaction.setTransactionTimeout(transactionTimeout);
+            }
         }
         catch (SystemException e)
         {
@@ -153,7 +165,6 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
      *
      * @param entityManagerEntry entry of the current entity-manager
      */
-
     @Override
     protected void beforeProceed(EntityManagerEntry entityManagerEntry)
     {
@@ -167,16 +178,40 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
             return userTransaction;
         }
 
-        return JndiUtils.lookup(USER_TRANSACTION_JNDI_NAME, UserTransaction.class);
+        try
+        {
+            return JndiUtils.lookup(USER_TRANSACTION_JNDI_NAME, UserTransaction.class);
+        }
+        catch (Exception ne)
+        {
+            // do nothing it was just a try
+            return null;
+        }
+    }
+
+    protected TransactionSynchronizationRegistry resolveTransactionRegistry()
+    {
+        return JndiUtils.lookup(TRANSACTION_SYNC_REGISTRY_JNDI_NAME, TransactionSynchronizationRegistry.class);
     }
 
     private class UserTransactionAdapter implements EntityTransaction
     {
         private final UserTransaction userTransaction;
+        private TransactionSynchronizationRegistry transactionSynchronizationRegistry = null;
 
         public UserTransactionAdapter()
         {
             this.userTransaction = resolveUserTransaction();
+
+            if (this.userTransaction == null)
+            {
+                transactionSynchronizationRegistry = resolveTransactionRegistry();
+
+                if (transactionSynchronizationRegistry.getTransactionStatus() != Status.STATUS_ACTIVE)
+                {
+                    throw new RuntimeException("invalid state/badly configured JTA datasource");
+                }
+            }
         }
 
         /**
@@ -187,6 +222,12 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
         @Override
         public void begin()
         {
+
+            if (this.userTransaction == null)
+            {
+                throw new IllegalStateException("cannot begin UserTransaction in CMT environment");
+            }
+
             try
             {
                 //2nd check (already done by #isActive triggered by ResourceLocalTransactionStrategy
directly before)
@@ -214,6 +255,12 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
         @Override
         public void commit()
         {
+            if (this.userTransaction == null)
+            {
+                throw new IllegalStateException("cannot commit UserTransaction in CMT environment");
+            }
+
+
             try
             {
                 if (isTransactionReadyToCommit())
@@ -241,6 +288,11 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
         @Override
         public void rollback()
         {
+            if (this.userTransaction == null)
+            {
+                throw new IllegalStateException("cannot rollback UserTransaction in CMT environment");
+            }
+
             try
             {
                 if (isTransactionAllowedToRollback())
@@ -259,7 +311,15 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
         {
             try
             {
-                this.userTransaction.setRollbackOnly();
+                if (this.userTransaction != null)
+                {
+                    this.userTransaction.setRollbackOnly();
+                }
+                else
+                {
+                    this.transactionSynchronizationRegistry.setRollbackOnly();
+                }
+
             }
             catch (SystemException e)
             {
@@ -272,7 +332,7 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
         {
             try
             {
-                return this.userTransaction.getStatus() == Status.STATUS_MARKED_ROLLBACK;
+                return this.getStatus() == Status.STATUS_MARKED_ROLLBACK;
             }
             catch (SystemException e)
             {
@@ -289,8 +349,8 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
             //we can't use the status of the overall
             try
             {
-                return this.userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION &&
-                        this.userTransaction.getStatus() != Status.STATUS_UNKNOWN; //TODO
re-visit it
+                return this.getStatus() != Status.STATUS_NO_TRANSACTION &&
+                        this.getStatus() != Status.STATUS_UNKNOWN; //TODO re-visit it
             }
             catch (SystemException e)
             {
@@ -302,16 +362,28 @@ public class BeanManagedUserTransactionStrategy extends ResourceLocalTransaction
         {
             //if the following gets changed, it needs to be tested with different constellations
             //(normal exception, timeout,...) as well as servers
-            return  this.userTransaction.getStatus() != Status.STATUS_COMMITTED &&
-                    this.userTransaction.getStatus() != Status.STATUS_NO_TRANSACTION &&
-                    this.userTransaction.getStatus() != Status.STATUS_UNKNOWN;
+            return this.getStatus() != Status.STATUS_COMMITTED &&
+                    this.getStatus() != Status.STATUS_NO_TRANSACTION &&
+                    this.getStatus() != Status.STATUS_UNKNOWN;
         }
 
         protected boolean isTransactionReadyToCommit() throws SystemException
         {
-            return this.userTransaction.getStatus() == Status.STATUS_ACTIVE ||
-                    this.userTransaction.getStatus() == Status.STATUS_PREPARING ||
-                    this.userTransaction.getStatus() == Status.STATUS_PREPARED;
+            return this.getStatus() == Status.STATUS_ACTIVE ||
+                    this.getStatus() == Status.STATUS_PREPARING ||
+                    this.getStatus() == Status.STATUS_PREPARED;
+        }
+
+        protected int getStatus() throws SystemException
+        {
+            if (this.userTransaction != null)
+            {
+                return this.userTransaction.getStatus();
+            }
+            else
+            {
+                return this.transactionSynchronizationRegistry.getTransactionStatus();
+            }
         }
     }
 }


Mime
View raw message