Return-Path: X-Original-To: apmail-deltaspike-commits-archive@www.apache.org Delivered-To: apmail-deltaspike-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 893C610931 for ; Tue, 21 Jan 2014 16:56:56 +0000 (UTC) Received: (qmail 27975 invoked by uid 500); 21 Jan 2014 16:56:55 -0000 Delivered-To: apmail-deltaspike-commits-archive@deltaspike.apache.org Received: (qmail 27933 invoked by uid 500); 21 Jan 2014 16:56:55 -0000 Mailing-List: contact commits-help@deltaspike.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@deltaspike.apache.org Delivered-To: mailing list commits@deltaspike.apache.org Received: (qmail 27926 invoked by uid 99); 21 Jan 2014 16:56:55 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jan 2014 16:56:55 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 3362953F96; Tue, 21 Jan 2014 16:56:55 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: struberg@apache.org To: commits@deltaspike.apache.org Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: git commit: DELTASPIKE-507 fallback to TransactionSynchronisationRegistry Date: Tue, 21 Jan 2014 16:56:55 +0000 (UTC) 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 Authored: Tue Jan 21 17:55:50 2014 +0100 Committer: Mark Struberg 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(); + } } } }