diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java index fef9853c8d..0e5df22511 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransaction.java @@ -357,4 +357,8 @@ default int depth() { */ void postRollback(Throwable cause); + /** + * Set the transaction to be inactive via external transaction manager. + */ + void deactivateExternal(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java index 28a29cb594..9c2057a4a5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiTransactionProxy.java @@ -447,4 +447,9 @@ public void postCommit() { public void postRollback(Throwable cause) { transaction.postRollback(cause); } + + @Override + public void deactivateExternal() { + transaction.deactivateExternal(); + } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java index 1fd2cd22c5..1353a217db 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/ImplicitReadOnlyTransaction.java @@ -609,6 +609,11 @@ public void postRollback(Throwable cause) { // do nothing } + @Override + public void deactivateExternal() { + this.active = false; + } + /** * Return true if the transaction is active. */ diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java index 9aac861c2a..e1b3b773ef 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JdbcTransaction.java @@ -1082,6 +1082,11 @@ public boolean isActive() { return active; } + @Override + public void deactivateExternal() { + this.active = false; + } + @Override public final boolean isPersistCascade() { return persistCascade; diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java index afa032abef..25324d9569 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/JtaTransactionManager.java @@ -94,9 +94,14 @@ public Object getCurrentTransaction() { // check current Ebean transaction SpiTransaction currentEbeanTransaction = scope.inScope(); if (currentEbeanTransaction != null) { - // NOT expecting this so log WARNING - log.log(WARNING, "JTA Transaction - no current txn BUT using current Ebean one {0}", currentEbeanTransaction.id()); - return currentEbeanTransaction; + if (currentEbeanTransaction.isActive()) { + // NOT expecting this so log WARNING + log.log(WARNING, "JTA Transaction - no current txn BUT using current Ebean one {0}", currentEbeanTransaction.id()); + return currentEbeanTransaction; + } else { + log.log(DEBUG, "JTA Transaction - clearing inActive Ebean transaction {0}", currentEbeanTransaction.id()); + scope.clearExternal(); + } } UserTransaction ut = userTransaction(); @@ -186,27 +191,27 @@ public void beforeCompletion() { @Override public void afterCompletion(int status) { - switch (status) { - case Status.STATUS_COMMITTED: - log.log(DEBUG, "Jta Txn [{0}] committed", transaction.id()); - transaction.postCommit(); - // Remove this transaction object as it is completed - transactionManager.scope().clearExternal(); - break; - - case Status.STATUS_ROLLEDBACK: - log.log(DEBUG, "Jta Txn [{0}] rollback", transaction.id()); - transaction.postRollback(null); - // Remove this transaction object as it is completed - transactionManager.scope().clearExternal(); - break; - - default: - log.log(DEBUG, "Jta Txn [{0}] status:{1}", transaction.id(), status); + try { + switch (status) { + case Status.STATUS_COMMITTED: + log.log(DEBUG, "Jta Txn [{0}] committed", transaction.id()); + transaction.postCommit(); + break; + + case Status.STATUS_ROLLEDBACK: + log.log(DEBUG, "Jta Txn [{0}] rollback", transaction.id()); + transaction.postRollback(null); + break; + + default: + log.log(DEBUG, "Jta Txn [{0}] status:{1}", transaction.id(), status); + } + } finally { + transaction.deactivateExternal(); + transactionManager.scope().clearExternal(); + // No matter the completion status of the transaction, we release the connection we got from the pool. + JdbcClose.close(transaction.internalConnection()); } - - // No matter the completion status of the transaction, we release the connection we got from the pool. - JdbcClose.close(transaction.internalConnection()); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java index 886a091bbc..c18633a79a 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/transaction/NoTransaction.java @@ -117,6 +117,10 @@ public void postRollback(Throwable cause) { // do nothing } + @Override + public void deactivateExternal() { + // do nothing + } @Override public boolean isLogSql() {