| 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 |