TxManager.java |
/* * JBossMQ, the OpenSource JMS implementation * * Distributable under LGPL license. See terms of license at gnu.org. */ package org.jboss.mq.pm; import javax.jms.JMSException; import org.jboss.mq.ConnectionToken; import org.jboss.mq.SpyJMSException; import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap; /** * This class allows provides the base for user supplied persistence packages. * * @author Hiram Chirino (Cojonudo14@hotmail.com) * @author Paul Kendall (paul.kendall@orion.co.nz) * @author <a href="mailto:adrian@jboss.org">Adrian Brock</a> * @version $Revision: 1.6.6.1 $ */ public class TxManager { // Constants ----------------------------------------------------- // Attributes ---------------------------------------------------- /** The persistence manager */ PersistenceManager persistenceManager; /** Maps Global transactions to local transactions */ ConcurrentHashMap globalToLocal = new ConcurrentHashMap(); /** * Create a new TxManager * * @param pm the persistence manager */ // Static -------------------------------------------------------- // Constructors -------------------------------------------------- public TxManager(PersistenceManager pm) { persistenceManager = pm; } // Public -------------------------------------------------------- /** * Return the local transaction id for a distributed transaction id. * * @param dc the connection * @param xid the transaction id * @return The Prepared transaction * @exception javax.jms.JMSException Description of Exception */ public final Tx getPrepared(ConnectionToken dc, Object xid) throws JMSException { GlobalXID gxid = new GlobalXID(dc, xid); Tx txid = (Tx) globalToLocal.get(gxid); if (txid == null) throw new SpyJMSException("Transaction does not exist from: " + dc.getClientID() + " xid=" + xid); return txid; } /** * Create and return a unique transaction id. * * @return the transaction id * @exception JMSException for any error */ public final Tx createTx() throws JMSException { Tx txId = persistenceManager.createPersistentTx(); return txId; } /** * Commit the transaction to the persistent store. * * @param txId the transaction * @exception JMSException for any error */ public final void commitTx(Tx txId) throws JMSException { txId.commit(persistenceManager); } /** * Add an operation for after a commit * * @param txId the transaction * @param task the task * @throws JMSException for any error */ public void addPostCommitTask(Tx txId, Runnable task) throws JMSException { if (txId == null) { task.run(); return; } txId.addPostCommitTask(task); } /** * Rollback the transaction. * * @param txId the transaction * @exception JMSException for any error */ public void rollbackTx(Tx txId) throws JMSException { txId.rollback(persistenceManager); } /** * Add an operation for after a rollback * * @param txId the transaction * @param task the task * @throws JMSException for any error */ public void addPostRollbackTask(Tx txId, Runnable task) throws JMSException { if (txId == null) return; txId.addPostRollbackTask(task); } /** * Create and return a unique transaction id. Given a distributed connection * and a transaction id object, allocate a unique local transaction id if * the remote id is not already known. * * @param dc the connection token * @param xid the xid * @return the transaction * @exception JMSException for any error */ public Tx createTx(ConnectionToken dc, Object xid) throws JMSException { GlobalXID gxid = new GlobalXID(dc, xid); if (globalToLocal.containsKey(gxid)) throw new SpyJMSException("Duplicate transaction from: " + dc.getClientID() + " xid=" + xid); Tx txId = createTx(); globalToLocal.put(gxid, txId); //Tasks to remove the global to local mappings on commit/rollback txId.addPostCommitTask(gxid); txId.addPostRollbackTask(gxid); return txId; } // Package protected --------------------------------------------- // Protected ----------------------------------------------------- // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- /** * A global transaction */ class GlobalXID implements Runnable { ConnectionToken dc; Object xid; GlobalXID(ConnectionToken dc, Object xid) { this.dc = dc; this.xid = xid; } public boolean equals(Object obj) { if (obj == null) { return false; } if (obj.getClass() != GlobalXID.class) { return false; } return ((GlobalXID) obj).xid.equals(xid) && ((GlobalXID) obj).dc.equals(dc); } public int hashCode() { return xid.hashCode(); } public void run() { globalToLocal.remove(this); } } }
TxManager.java |