FileDocCategorySizeDatePackage
TransactionSynchronizer.javaAPI DocJBoss 4.2.18298Fri Jul 13 21:01:18 BST 2007org.jboss.resource.connectionmanager

TransactionSynchronizer

public class TransactionSynchronizer extends Object implements Synchronization
Organizes transaction synchronization done by JCA.

This class exists to make sure all Tx synchronizations are invoked before the cached connection manager closes any closed connections.

author
Adrian Brock
version
$Revision: 57189 $

Fields Summary
private static final Logger
log
The logger
protected static org.jboss.tm.TransactionLocal
txSynchs
The transaction synchronizations
protected Transaction
tx
The transaction
protected Thread
enlistingThread
The enlisting thread
protected ArrayList
unenlisted
Unenlisted
protected ArrayList
enlisted
Enlisted
protected Synchronization
ccmSynch
The cached connection manager synchronization
Constructors Summary
private TransactionSynchronizer(Transaction tx)
Create a new transaction synchronizer

param
tx the transaction to synchronize with

      this.tx = tx;
   
Methods Summary
synchronized voidaddEnlisted(javax.transaction.Synchronization synch)
The synchronization is now enlisted

param
synch the synchronization

      if (enlisted == null)
         enlisted = new ArrayList();
      enlisted.add(synch);
   
synchronized voidaddUnenlisted(javax.transaction.Synchronization synch)
Add a new Tx synchronization that has not been enlisted

param
synch the synchronization

      if (unenlisted == null)
         unenlisted = new ArrayList();
      unenlisted.add(synch);
   
public voidafterCompletion(int status)

      if (enlisted != null)
      {
         int i = 0;
         while (i < enlisted.size())
         {
            Synchronization synch = (Synchronization) enlisted.get(i);
            invokeAfter(synch, status);
            ++i;
         }
      }
      
      if (ccmSynch != null)
         invokeAfter(ccmSynch, status);
   
public voidbeforeCompletion()

      if (enlisted != null)
      {
         int i = 0;
         while (i < enlisted.size())
         {
            Synchronization synch = (Synchronization) enlisted.get(i);
            invokeBefore(synch);
            ++i;
         }
      }
      
      if (ccmSynch != null)
         invokeBefore(ccmSynch);
   
synchronized voidenlisted()
This thread has finished enlisting

      Thread currentThread = Thread.currentThread();
      if (enlistingThread == null || enlistingThread != currentThread)
      {
         log.warn("Thread " + currentThread + " not the enlisting thread " + enlistingThread, new Exception("STACKTRACE"));
         return;
      }
      enlistingThread = null;
      notifyAll();
   
static javax.transaction.SynchronizationgetCCMSynchronization(javax.transaction.Transaction tx)
Check whether we have a CCM synchronization

param
tx the transaction

      TransactionSynchronizer ts = (TransactionSynchronizer) txSynchs.get(tx);
      if (ts != null)
         return ts.ccmSynch;
      else
         return null;
   
static org.jboss.resource.connectionmanager.TransactionSynchronizergetRegisteredSynchronizer(javax.transaction.Transaction tx)
Get a registered transaction synchronizer.

param
tx the transaction
return
the registered transaction synchronizer for this transaction
throws
RolledbackException if the transaction is already rolled back
throws
SystemException for an error in the tranaction manager

      TransactionSynchronizer result = (TransactionSynchronizer) txSynchs.get(tx);
      if (result == null)
      {
         result = new TransactionSynchronizer(tx);
         tx.registerSynchronization(result);
         txSynchs.set(tx, result);
      }
      return result;
   
synchronized java.util.ArrayListgetUnenlisted()
Get the unenlisted synchronizations and say we are enlisting if some are returned.

return
the unenlisted synchronizations

      Thread currentThread = Thread.currentThread();
      while (enlistingThread != null && enlistingThread != currentThread)
      {
         boolean interrupted = false;
         try
         {
            wait();
         }
         catch (InterruptedException e)
         {
            interrupted = true;
         }
         if (interrupted)
            currentThread.interrupt();
      }
      ArrayList result = unenlisted;
      unenlisted = null;
      if (result != null)
         enlistingThread = currentThread;
      return result;
   
protected voidinvokeAfter(javax.transaction.Synchronization synch, int status)
Invoke an afterCompletion

param
synch the synchronization
param
status the status of the transaction

      try
      {
         synch.afterCompletion(status);
      }
      catch (Throwable t)
      {
         log.warn("Transaction " + tx + " error in after completion " + synch, t);
      }
   
protected voidinvokeBefore(javax.transaction.Synchronization synch)
Invoke a beforeCompletion

param
synch the synchronization

      try
      {
         synch.beforeCompletion();
      }
      catch (Throwable t)
      {
         log.warn("Transaction " + tx + " error in before completion " + synch, t);
      }
   
static voidlock(javax.transaction.Transaction tx)
Lock for the given transaction

param
tx the transaction

      try
      {
         txSynchs.lock(tx);
      }
      catch (InterruptedException e)
      {
         throw new NestedRuntimeException("Unable to get synchronization", e);
      }
   
static voidregisterCCMSynchronization(javax.transaction.Transaction tx, javax.transaction.Synchronization synch)
Register a new CCM synchronization

param
tx the transaction
param
synch the synchronization
throws
RolledbackException if the transaction is already rolled back
throws
SystemException for an error in the tranaction manager

      TransactionSynchronizer ts = getRegisteredSynchronizer(tx);
      ts.ccmSynch = synch;
   
synchronized booleanremoveEnlisted(javax.transaction.Synchronization synch)
Remove an enlisted synchronization

param
synch the synchronization
return
true when the synchronization was enlisted

      return enlisted.remove(synch);
   
public static voidsetTransactionManager(javax.transaction.TransactionManager tm)
Initialization


     
       
   
      txSynchs = new TransactionLocal(tm);
   
static voidunlock(javax.transaction.Transaction tx)
Unlock for the given transaction

param
tx the transaction

      txSynchs.unlock(tx);