/* * Copyright (c) 2007 Allianz Global Risks * * This software is confidential and proprietary information of Allianz. * You shall not disclose such confidential information and shall use it only * in accordance with the terms of the agreements you entered into with Allianz. */ package com.agcs.common.transactions; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.persistence.EntityManager; import javax.transaction.Status; import javax.transaction.UserTransaction; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Install; import org.jboss.seam.annotations.Logger; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; import org.jboss.seam.log.Log; import org.jboss.seam.transaction.Transaction; import com.agcs.pricing.dao.PricingDAOException; /** * @author alexander * @version $Id$ * */ @Name("transactionalInvoker") @Scope(ScopeType.STATELESS) @Install(precedence = Install.DEPLOYMENT) public class TransactionalInvokerPojo implements TransactionalInvoker { /** The class logger. */ @Logger private static Log logger; /** The pricing entity manager. */ @In(create = true) private EntityManager pricingEm; @In(value = "org.jboss.seam.transaction.transaction", create=true) private UserTransaction transaction; /** Public default constructor. */ public TransactionalInvokerPojo() { } /** * @see com.agcs.common.transactions.TransactionalInvoker#doInNewTransaction() * {@inheritDoc} */ public void doInNewTransaction(TransactionCallback tocall) { boolean reopenConnection = false; try { // commit the old transaction switch (transaction.getStatus()) { case Status.STATUS_ACTIVE: logger.debug("Closing running transaction before entering new transaction block: #0", tocall); transaction.commit(); reopenConnection = true; break; case Status.STATUS_MARKED_ROLLBACK: logger.warn("Rollback of transaction marked as roll back: #0", tocall); transaction.rollback(); reopenConnection = true; break; /** change for JBoss 4.2.3 */ case Status.STATUS_ROLLEDBACK: logger.warn("The transaction was rollbacked: #0", tocall); try { transaction.rollback(); } catch (IllegalStateException ex) { /* ignore */ // see: http://www.jboss.org/index.html?module=bb&op=viewtopic&t=138915&postdays=0&postorder=asc&start=0 } reopenConnection = true; break; case Status.STATUS_NO_TRANSACTION: break; default: logger.warn("Found transaction in unexpected state #0: #1", new Integer(transaction.getStatus()), tocall); } // begin the transaction logger.debug("Opening new transaction for block: #0", tocall); transaction.begin(); pricingEm.joinTransaction(); // run the transactional logic tocall.executeTransactionalLogic(); // commit the transaction and reopen a new one if one was there before logger.debug("Committing transaction for block: #0", tocall); transaction.commit(); if (reopenConnection) { logger.debug("Reopening transaction after transaction block: #0", tocall); transaction.begin(); pricingEm.joinTransaction(); } logger.debug("Transaction for #0 is committing" , tocall); } catch (Throwable e) { if (transaction != null) { try { // roll back due to an exception logger.debug("Transaction rollback due to exception #0", e); transaction.rollback(); if (reopenConnection) { transaction.begin(); pricingEm.joinTransaction(); } } catch (Exception e1) { logger.error("Transaction rollback failed with exception #0", e1); } } if (e instanceof RuntimeException) { throw (RuntimeException)e; } else { throw new RuntimeException(e); } } } /** * @see com.agcs.common.transactions.TransactionalInvoker#doInNewTransaction() * {@inheritDoc} */ public void doInMandatoryTransaction(TransactionCallback tocall) { logger.debug("Executing in mandatory transaction: #0", tocall); try { tocall.executeTransactionalLogic(); } catch (RuntimeException e) { logger.debug("Execution #0 with mandatory had runtime exception", tocall); } } /** * @see com.agcs.common.transactions.TransactionalInvoker#doInNewTransaction() * {@inheritDoc} */ public void doWithoutTransaction(TransactionCallback tocall) { logger.debug("Executing without transaction: #0", tocall); try { tocall.executeTransactionalLogic(); } catch (RuntimeException e) { logger.debug("Execution for #0 had runtime exception", tocall); } } /** * @see com.agcs.common.transactions.TransactionalInvoker#doInNewTransaction() * {@inheritDoc} */ public void doNeverInTransaction(TransactionCallback tocall) { logger.debug("Executing and make sure there is no transaction active: #0", tocall); try { tocall.executeTransactionalLogic(); } catch (RuntimeException e) { logger.debug("Execution for #0 had runtime exception", tocall); } } }