From 8879bd2be87777794987868e64ed22c74ad8657b Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Fri, 31 Jul 2015 22:46:20 +1200 Subject: [PATCH] No effective change - format only --- .../transaction/JtaTransactionManager.java | 375 +++++++++--------- 1 file changed, 186 insertions(+), 189 deletions(-) diff --git a/src/main/java/com/avaje/ebeaninternal/server/transaction/JtaTransactionManager.java b/src/main/java/com/avaje/ebeaninternal/server/transaction/JtaTransactionManager.java index 6a6f3d4ef..8162164fa 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/transaction/JtaTransactionManager.java +++ b/src/main/java/com/avaje/ebeaninternal/server/transaction/JtaTransactionManager.java @@ -1,5 +1,10 @@ package com.avaje.ebeaninternal.server.transaction; +import com.avaje.ebean.config.ExternalTransactionManager; +import com.avaje.ebeaninternal.api.SpiTransaction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import javax.naming.InitialContext; import javax.naming.NamingException; import javax.persistence.PersistenceException; @@ -14,216 +19,208 @@ import javax.transaction.SystemException; import javax.transaction.TransactionSynchronizationRegistry; import javax.transaction.UserTransaction; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.avaje.ebean.config.ExternalTransactionManager; -import com.avaje.ebeaninternal.api.SpiTransaction; - /** * Hook into external JTA transaction manager. - * - * @author rbygrave */ public class JtaTransactionManager implements ExternalTransactionManager { - private static final Logger logger = LoggerFactory.getLogger(JtaTransactionManager.class); + private static final Logger logger = LoggerFactory.getLogger(JtaTransactionManager.class); - private static final String EBEAN_TXN_RESOURCE = "EBEAN_TXN_RESOURCE"; - - /** - * The data source. - */ - private DataSource dataSource; + private static final String EBEAN_TXN_RESOURCE = "EBEAN_TXN_RESOURCE"; - /** - * The Ebean transaction manager. - */ - private TransactionManager transactionManager; + /** + * The data source. + */ + private DataSource dataSource; - /** - * The EbeanServer name. - */ - private String serverName; - - /** - * Instantiates a new spring aware transaction scope manager. - */ - public JtaTransactionManager() { + /** + * The Ebean transaction manager. + */ + private TransactionManager transactionManager; + + /** + * The EbeanServer name. + */ + private String serverName; + + /** + * Instantiates a new spring aware transaction scope manager. + */ + public JtaTransactionManager() { + } + + /** + * Initialise this with the Ebean internal transaction manager. + */ + public void setTransactionManager(Object txnMgr) { + + // RB: At this stage not exposing TransactionManager to + // the public API and hence the Object type and casting here + + this.transactionManager = (TransactionManager) txnMgr; + this.dataSource = transactionManager.getDataSource(); + this.serverName = transactionManager.getServerName(); + } + + private TransactionSynchronizationRegistry getSyncRegistry() { + try { + InitialContext ctx = new InitialContext(); + return (TransactionSynchronizationRegistry) ctx.lookup("java:comp/TransactionSynchronizationRegistry"); + } catch (NamingException e) { + throw new PersistenceException(e); + } + } + + private UserTransaction getUserTransaction() { + try { + InitialContext ctx = new InitialContext(); + return (UserTransaction) ctx.lookup("java:comp/UserTransaction"); + } catch (NamingException e) { + // assuming CMT + return new DummyUserTransaction(); + } + } + + /** + * Looks for a current Spring managed transaction and wraps/returns that as a Ebean transaction. + *

+ * Returns null if there is no current spring transaction (lazy loading outside a spring txn etc). + *

+ */ + public Object getCurrentTransaction() { + + TransactionSynchronizationRegistry syncRegistry = getSyncRegistry(); + + SpiTransaction t = (SpiTransaction) syncRegistry.getResource(EBEAN_TXN_RESOURCE); + if (t != null) { + // we have already seen this transaction + return t; } - /** - * Initialise this with the Ebean internal transaction manager. - */ - public void setTransactionManager(Object txnMgr) { - - // RB: At this stage not exposing TransactionManager to - // the public API and hence the Object type and casting here - - this.transactionManager = (TransactionManager) txnMgr; - this.dataSource = transactionManager.getDataSource(); - this.serverName = transactionManager.getServerName(); + // check current Ebean transaction + SpiTransaction currentEbeanTransaction = DefaultTransactionThreadLocal.get(serverName); + if (currentEbeanTransaction != null) { + // NOT expecting this so log WARNING + String msg = "JTA Transaction - no current txn BUT using current Ebean one " + currentEbeanTransaction.getId(); + logger.warn(msg); + return currentEbeanTransaction; } - private TransactionSynchronizationRegistry getSyncRegistry() { - try { - InitialContext ctx = new InitialContext(); - return (TransactionSynchronizationRegistry)ctx.lookup("java:comp/TransactionSynchronizationRegistry"); - } catch (NamingException e){ - throw new PersistenceException(e); - } - } - - private UserTransaction getUserTransaction() { - try { - InitialContext ctx = new InitialContext(); - return (UserTransaction) ctx.lookup("java:comp/UserTransaction"); - } catch (NamingException e){ - // assuming CMT - return new DummyUserTransaction(); - } - } - - /** - * Looks for a current Spring managed transaction and wraps/returns that as a Ebean transaction. - *

- * Returns null if there is no current spring transaction (lazy loading outside a spring txn etc). - *

- */ - public Object getCurrentTransaction() { - - TransactionSynchronizationRegistry syncRegistry = getSyncRegistry(); - - SpiTransaction t = (SpiTransaction)syncRegistry.getResource(EBEAN_TXN_RESOURCE); - if (t != null){ - // we have already seen this transaction - return t; - } - - // check current Ebean transaction - SpiTransaction currentEbeanTransaction = DefaultTransactionThreadLocal.get(serverName); - if (currentEbeanTransaction != null){ - // NOT expecting this so log WARNING - String msg = "JTA Transaction - no current txn BUT using current Ebean one "+currentEbeanTransaction.getId(); - logger.warn(msg); - return currentEbeanTransaction; - } - - UserTransaction ut = getUserTransaction(); - if (ut == null){ - // no current JTA transaction - if (logger.isDebugEnabled()){ - logger.debug("JTA Transaction - no current txn"); - } - return null; - } - - // This is a transaction that Ebean has not seen before. - - // "wrap" it in a Ebean specific JtaTransaction - String txnId = String.valueOf(System.currentTimeMillis()); - JtaTransaction newTrans = new JtaTransaction(txnId, true, ut, dataSource, transactionManager); - - // create and register transaction listener - JtaTxnListener txnListener = createJtaTxnListener(newTrans); - - syncRegistry.putResource(EBEAN_TXN_RESOURCE, newTrans); - syncRegistry.registerInterposedSynchronization(txnListener); - - // also put in Ebean ThreadLocal - DefaultTransactionThreadLocal.set(serverName, newTrans); - return newTrans; + UserTransaction ut = getUserTransaction(); + if (ut == null) { + // no current JTA transaction + if (logger.isDebugEnabled()) { + logger.debug("JTA Transaction - no current txn"); + } + return null; } - - /** - * Create a listener to register with JTA to enable Ebean to be - * notified when transactions commit and rollback. - *

- * This is used by Ebean to notify it's appropriate listeners and maintain it's server - * cache etc. - *

- */ - private JtaTxnListener createJtaTxnListener(SpiTransaction t) { - return new JtaTxnListener(transactionManager, t); - } - - private static class DummyUserTransaction implements UserTransaction { + // This is a transaction that Ebean has not seen before. - public void begin() throws NotSupportedException, SystemException { - } + // "wrap" it in a Ebean specific JtaTransaction + String txnId = String.valueOf(System.currentTimeMillis()); + JtaTransaction newTrans = new JtaTransaction(txnId, true, ut, dataSource, transactionManager); - public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, - SecurityException, IllegalStateException, SystemException { - } + // create and register transaction listener + JtaTxnListener txnListener = createJtaTxnListener(newTrans); - public int getStatus() throws SystemException { - return 0; - } + syncRegistry.putResource(EBEAN_TXN_RESOURCE, newTrans); + syncRegistry.registerInterposedSynchronization(txnListener); - public void rollback() throws IllegalStateException, SecurityException, SystemException { - } + // also put in Ebean ThreadLocal + DefaultTransactionThreadLocal.set(serverName, newTrans); + return newTrans; + } - public void setRollbackOnly() throws IllegalStateException, SystemException { - } - public void setTransactionTimeout(int seconds) throws SystemException { - } + /** + * Create a listener to register with JTA to enable Ebean to be + * notified when transactions commit and rollback. + *

+ * This is used by Ebean to notify it's appropriate listeners and maintain it's server + * cache etc. + *

+ */ + private JtaTxnListener createJtaTxnListener(SpiTransaction t) { + return new JtaTxnListener(transactionManager, t); + } + + private static class DummyUserTransaction implements UserTransaction { + + public void begin() throws NotSupportedException, SystemException { } - /** - * A JTA Transaction Synchronization that we register to get notified when a - * managed transaction has been committed or rolled back. - *

- * When Ebean is notified (of the commit/rollback) it can then manage its - * cache, notify BeanPersistListeners etc. - *

- */ - private static class JtaTxnListener implements Synchronization { - - private final TransactionManager transactionManager; - - private final SpiTransaction transaction; - - private final String serverName; - - private JtaTxnListener(TransactionManager transactionManager, SpiTransaction t){ - this.transactionManager = transactionManager; - this.transaction = t; - this.serverName = transactionManager.getServerName(); - } - - public void beforeCompletion() { - // Future note: for JPA2 locking we will - // have beforeCommit events to fire - } - - public void afterCompletion(int status) { - - switch (status) { - case Status.STATUS_COMMITTED: - if (logger.isDebugEnabled()){ - logger.debug("Jta Txn ["+transaction.getId()+"] committed"); - } - transactionManager.notifyOfCommit(transaction); - // Remove this transaction object as it is completed - DefaultTransactionThreadLocal.replace(serverName, null); - break; - - case Status.STATUS_ROLLEDBACK: - if (logger.isDebugEnabled()){ - logger.debug("Jta Txn ["+transaction.getId()+"] rollback"); - } - transactionManager.notifyOfRollback(transaction, null); - // Remove this transaction object as it is completed - DefaultTransactionThreadLocal.replace(serverName, null); - break; - - default: - logger.debug("Jta Txn ["+transaction.getId()+"] status:"+status); - } - - } + public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, + SecurityException, IllegalStateException, SystemException { } - + + public int getStatus() throws SystemException { + return 0; + } + + public void rollback() throws IllegalStateException, SecurityException, SystemException { + } + + public void setRollbackOnly() throws IllegalStateException, SystemException { + } + + public void setTransactionTimeout(int seconds) throws SystemException { + } + } + + /** + * A JTA Transaction Synchronization that we register to get notified when a + * managed transaction has been committed or rolled back. + *

+ * When Ebean is notified (of the commit/rollback) it can then manage its + * cache, notify BeanPersistListeners etc. + *

+ */ + private static class JtaTxnListener implements Synchronization { + + private final TransactionManager transactionManager; + + private final SpiTransaction transaction; + + private final String serverName; + + private JtaTxnListener(TransactionManager transactionManager, SpiTransaction t) { + this.transactionManager = transactionManager; + this.transaction = t; + this.serverName = transactionManager.getServerName(); + } + + public void beforeCompletion() { + // Future note: for JPA2 locking we will + // have beforeCommit events to fire + } + + public void afterCompletion(int status) { + + switch (status) { + case Status.STATUS_COMMITTED: + if (logger.isDebugEnabled()) { + logger.debug("Jta Txn [" + transaction.getId() + "] committed"); + } + transactionManager.notifyOfCommit(transaction); + // Remove this transaction object as it is completed + DefaultTransactionThreadLocal.replace(serverName, null); + break; + + case Status.STATUS_ROLLEDBACK: + if (logger.isDebugEnabled()) { + logger.debug("Jta Txn [" + transaction.getId() + "] rollback"); + } + transactionManager.notifyOfRollback(transaction, null); + // Remove this transaction object as it is completed + DefaultTransactionThreadLocal.replace(serverName, null); + break; + + default: + logger.debug("Jta Txn [" + transaction.getId() + "] status:" + status); + } + + } + } + }