Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * IronJacamar, a Java EE Connector Architecture implementation
   * Copyright 2006, Red Hat Inc, and individual contributors
   * as indicated by the @author tags. See the copyright.txt file in the
   * distribution for a full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 package org.jboss.jca.core.connectionmanager.transaction;
 
 
 import java.util.List;
 import java.util.Map;
 
 
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(s):
Adrian Brock
gurkanerdogdu
Version:
$Rev$
 
 public class TransactionSynchronizer implements Synchronization
 {
   
The logger
 
    private static CoreLogger log = Logger.getMessageLogger(CoreLogger.classTransactionSynchronizer.class.getName());

   
The records
 
    private static ConcurrentMap<TransactionRecordrecords =
       new ConcurrentHashMap<TransactionRecord>();
   
   
The transaction
 
    private Transaction tx;
   
   
The enlisting thread
 
    private Thread enlistingThread;
   
   
Unenlisted
 
    private List<Synchronizationunenlisted;
   
   
Enlisted
 
    private List<Synchronizationenlisted;
   
   
The cached connection manager synchronization
 
    private Synchronization ccmSynch;
   
   
Create a new transaction synchronizer

Parameters:
tx the transaction to synchronize with
 
    {
       this. = tx;
    }
   
   
Add a new Tx synchronization that has not been enlisted

Parameters:
synch the synchronization
 
    public synchronized void addUnenlisted(Synchronization synch)
    {
       if ( == null)
           = new ArrayList<Synchronization>(1);
 
       .add(synch);
   }
   
   
Get the unenlisted synchronizations and say we are enlisting if some are returned.

Returns:
the unenlisted synchronizations
   public synchronized List<SynchronizationgetUnenlisted()
   {
      Thread currentThread = Thread.currentThread();
      while ( != null &&  != currentThread)
      {
         boolean interrupted = false;
         try
         {
            wait();
         }
         catch (InterruptedException e)
         {
            interrupted = true;
         }
         if (interrupted)
            currentThread.interrupt();
      }
      List<Synchronizationresult = ;
       = null;
      if (result != null)
      {
          = currentThread;
      }
      return result;
   }
   
   
The synchronization is now enlisted

Parameters:
synch the synchronization
   public synchronized void addEnlisted(Synchronization synch)
   {
      if ( == null)
          = new ArrayList<Synchronization>(1);
      .add(synch);
   }
   
   
Remove an enlisted synchronization

Parameters:
synch the synchronization
Returns:
true when the synchronization was enlisted
   public synchronized boolean removeEnlisted(Synchronization synch)
   {
      return .remove(synch);
   }
   
   
This thread has finished enlisting.
   public synchronized void enlisted()
   {
      Thread currentThread = Thread.currentThread();
      if ( == null ||  != currentThread)
      {
         .threadIsnotEnlistingThread(currentThread
            new Exception("STACKTRACE"));
         return;
      }
       = null;
      notifyAll();
   }
   
   
Get a registered transaction synchronizer.

Parameters:
tx the transaction
tsr the transaction synchronization registry
Returns:
the registered transaction synchronizer for this transaction
Throws:
javax.transaction.SystemException sys. exception
javax.transaction.RollbackException rollback exception
                                                                   TransactionSynchronizationRegistry tsr)
   {
      Record record = .get(tx);
      if (record == null)
      {
         Record newRecord = new Record(new ReentrantLock(true), new TransactionSynchronizer(tx));
         record = .putIfAbsent(txnewRecord);
         if (record == null)
         {
            record = newRecord;
            if (tsr != null)
            {
               tsr.registerInterposedSynchronization(record.getTransactionSynchronizer());
            }
            else
            {
               tx.registerSynchronization(record.getTransactionSynchronizer());
            }
         }
      }
      return record.getTransactionSynchronizer();
   }

   
Check whether we have a CCM synchronization

Parameters:
tx the transaction
Returns:
synch
   {
      Record record = .get(tx);
      if (record != null)
         return record.getTransactionSynchronizer().;  
      return null;  
   }
   
   
Register a new CCM synchronization

Parameters:
tx the transaction
synch the synchronization
tsr the transaction synchronization registry
Throws:
java.lang.Exception e
   public static void registerCCMSynchronization(Transaction tx,
                                                 Synchronization synch,
                                                 TransactionSynchronizationRegistry tsr)
      throws Exception
   {
      ts.ccmSynch = synch;
   }

   
Lock for the given transaction

Parameters:
tx the transaction
tsr the transaction synchronization registry
Throws:
javax.transaction.SystemException sys. exception
javax.transaction.RollbackException rollback exception
   public static void lock(Transaction txTransactionSynchronizationRegistry tsr)
   {
      Record record = .get(tx);
      if (record == null)
      {
         Record newRecord = new Record(new ReentrantLock(true), new TransactionSynchronizer(tx));
         record = .putIfAbsent(txnewRecord);
         if (record == null)
         {
            record = newRecord;
            if (tsr != null)
            {
               tsr.registerInterposedSynchronization(record.getTransactionSynchronizer());
            }
            else
            {
               tx.registerSynchronization(record.getTransactionSynchronizer());
            }
         }
      }
      Lock lock = record.getLock();
      try
      {
         lock.lockInterruptibly();
      }
      catch (InterruptedException e)
      {
         throw new RuntimeException("Unable to get synchronization"e);
      }
   }
   
   
Unlock for the given transaction

Parameters:
tx the transaction
   public static void unlock(Transaction tx)
   {
      Record record = .get(tx);
      if (record != null)
         record.getLock().unlock();
   }

   
   public void beforeCompletion()
   {
      if ( != null)
      {
         for (Synchronization synch : )
         {
            invokeBefore(synch);
         }
      }
      
      if ( != null)
      {
         invokeBefore();  
      }
   }

   
   public void afterCompletion(int status)
   {
      if ( != null)
      {
         for (Synchronization synch : )
         {
            invokeAfter(synchstatus);
         }
      }
      
      if ( != null)
      {
         invokeAfter(status);  
      }
      // Cleanup the maps
      if (.remove() == null)
      {
         boolean found = false;
         Iterator<Map.Entry<TransactionRecord>> iterator = .entrySet().iterator();
         while (!found && iterator.hasNext())
         {
            Map.Entry<TransactionRecordnext = iterator.next();
            if (next.getValue().getTransactionSynchronizer().equals(this))
            {
               iterator.remove();
               found = true;
            }
         }
      }
   }

   
Invoke a beforeCompletion

Parameters:
synch the synchronization
   protected void invokeBefore(Synchronization synch)
   {
      try
      {
         synch.beforeCompletion();
      }
      catch (Throwable t)
      {
         .transactionErrorInBeforeCompletion(syncht);
      }
   }

   
Invoke an afterCompletion

Parameters:
synch the synchronization
status the status of the transaction
   protected void invokeAfter(Synchronization synchint status)
   {
      try
      {
         synch.afterCompletion(status);
      }
      catch (Throwable t)
      {
         .transactionErrorInAfterCompletion(syncht);
      }
   }   

   
A record for a transaction
   static class Record
   {
      private Lock lock;
      private TransactionSynchronizer txSync;

      
Constructor

Parameters:
lock The lock
txSync The transaction synchronizer
      Record(Lock lockTransactionSynchronizer txSync)
      {
         this. = lock;
         this. = txSync;
      }

      
Get the lock

Returns:
The value
      Lock getLock()
      {
         return ;
      }

      
Get the transaction synchronizer

Returns:
The synchronizer
      {
         return ;
      }
   }
New to GrepCode? Check out our FAQ X