Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.resource.adapter » jdbc » xa » [javadoc | source]
    1   /*
    2    * JBoss, Home of Professional Open Source.
    3    * Copyright 2006, Red Hat Middleware LLC, and individual contributors
    4    * as indicated by the @author tags. See the copyright.txt file in the
    5    * distribution for a full listing of individual contributors.
    6    *
    7    * This is free software; you can redistribute it and/or modify it
    8    * under the terms of the GNU Lesser General Public License as
    9    * published by the Free Software Foundation; either version 2.1 of
   10    * the License, or (at your option) any later version.
   11    *
   12    * This software is distributed in the hope that it will be useful,
   13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15    * Lesser General Public License for more details.
   16    *
   17    * You should have received a copy of the GNU Lesser General Public
   18    * License along with this software; if not, write to the Free
   19    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21    */
   22   package org.jboss.resource.adapter.jdbc.xa;
   23   
   24   import java.sql.SQLException;
   25   import java.util.Properties;
   26   
   27   import javax.resource.ResourceException;
   28   import javax.resource.spi.LocalTransaction;
   29   import javax.sql.XAConnection;
   30   import javax.transaction.xa.XAException;
   31   import javax.transaction.xa.XAResource;
   32   import javax.transaction.xa.Xid;
   33   
   34   import org.jboss.resource.JBossResourceException;
   35   import org.jboss.resource.adapter.jdbc.BaseWrapperManagedConnection;
   36   
   37   /**
   38    * XAManagedConnection
   39    * 
   40    * @author <a href="mailto:d_jencks@users.sourceforge.net">David Jencks </a>
   41    * @author <a href="mailto:adrian@jboss.com">Adrian Brock</a>
   42    * @author <a href="weston.price@jboss.com">Weston Price</a>
   43    * @version $Revision: 71788 $
   44    */
   45   public class XAManagedConnection extends BaseWrapperManagedConnection implements XAResource, LocalTransaction
   46   {
   47      protected final XAConnection xaConnection;
   48   
   49      protected final XAResource xaResource;
   50   
   51      protected Xid currentXid;
   52      
   53      public XAManagedConnection(XAManagedConnectionFactory mcf, XAConnection xaConnection, Properties props,
   54            int transactionIsolation, int psCacheSize) throws SQLException
   55      {
   56         super(mcf, xaConnection.getConnection(), props, transactionIsolation, psCacheSize);
   57         this.xaConnection = xaConnection;
   58         xaConnection.addConnectionEventListener(new javax.sql.ConnectionEventListener()
   59         {
   60            public void connectionClosed(javax.sql.ConnectionEvent ce)
   61            {
   62               //only we can do this, ignore
   63            }
   64   
   65            public void connectionErrorOccurred(javax.sql.ConnectionEvent ce)
   66            {
   67               SQLException ex = ce.getSQLException();
   68               broadcastConnectionError(ex);
   69            }
   70         });
   71         this.xaResource = xaConnection.getXAResource();
   72      }
   73      
   74      public void begin() throws ResourceException 
   75      {	
   76         lock();
   77         try
   78         {
   79            synchronized (stateLock)
   80            {
   81               if (inManagedTransaction == false)
   82               {
   83                  try
   84                  {
   85                     if (underlyingAutoCommit)
   86                     {
   87                        underlyingAutoCommit = false;
   88                        con.setAutoCommit(false);
   89                     }
   90                     checkState();
   91                     inManagedTransaction = true;
   92                  }
   93                  catch (SQLException e)
   94                  {
   95                     checkException(e);
   96                  }
   97               }
   98               else
   99                  throw new JBossResourceException("Trying to begin a nested local tx");
  100            }
  101         }
  102         finally
  103         {
  104            unlock();
  105         }
  106      }
  107      public void commit() throws ResourceException 
  108      {	
  109         lock();
  110         try
  111         {
  112            synchronized (stateLock)
  113            {
  114               if (inManagedTransaction)
  115                  inManagedTransaction = false;
  116            }
  117            try
  118            {
  119               con.commit();
  120            }
  121            catch (SQLException e)
  122            {
  123               checkException(e);
  124            }
  125         }
  126         finally
  127         {
  128            unlock();
  129         }
  130      }   
  131      
  132      public void rollback() throws ResourceException
  133      {
  134         lock();
  135         try
  136         {
  137            synchronized (stateLock)
  138            {
  139               if (inManagedTransaction)
  140                  inManagedTransaction = false;
  141            }
  142            try
  143            {
  144               con.rollback();
  145            }
  146            catch (SQLException e)
  147            {
  148               try
  149               {
  150                  checkException(e);
  151               }
  152               catch (Exception e2)
  153               {
  154               }
  155            }
  156         }
  157         finally
  158         {
  159            unlock();
  160         }
  161      }
  162      
  163      protected void broadcastConnectionError(SQLException e)
  164      {
  165         super.broadcastConnectionError(e);
  166      }
  167   
  168      public LocalTransaction getLocalTransaction() throws ResourceException
  169      {
  170         return this;
  171      }
  172   
  173      public XAResource getXAResource() throws ResourceException
  174      {
  175         return this;
  176      }
  177   
  178      public void destroy() throws ResourceException
  179      {
  180         try
  181         {
  182            super.destroy();
  183         }
  184         finally
  185         {
  186            try
  187            {
  188               xaConnection.close();
  189            }
  190            catch (SQLException e)
  191            {
  192               checkException(e);
  193            }
  194         }
  195      }
  196   
  197      public void start(Xid xid, int flags) throws XAException
  198      {
  199         lock();
  200         try
  201         {
  202            try
  203            {
  204               checkState();
  205            }
  206            catch (SQLException e)
  207            {
  208               getLog().warn("Error setting state ", e);
  209            }
  210   
  211            try
  212            {
  213               xaResource.start(xid, flags);
  214            }
  215            catch(XAException e)
  216            {
  217               //JBAS-3336 Connections that fail in enlistment should not be returned
  218               //to the pool
  219               if(isFailedXA(e.errorCode))
  220               {
  221                  broadcastConnectionError(e);  
  222               }
  223               
  224               throw e;
  225            }
  226            
  227            synchronized (stateLock)
  228            {
  229               currentXid = xid;
  230               inManagedTransaction = true;
  231            }
  232         }
  233         finally
  234         {
  235            unlock();
  236         }
  237      }
  238   
  239      public void end(Xid xid, int flags) throws XAException
  240      {
  241         lock();
  242         try
  243         {
  244            try
  245            {
  246               xaResource.end(xid, flags);
  247            }
  248            catch(XAException e)
  249            {
  250               broadcastConnectionError(e);
  251               throw e;
  252            }
  253   
  254            
  255            //we want to allow ending transactions that are not the current
  256            //one. When one does this, inManagedTransaction is still true.
  257            synchronized (stateLock)
  258            {
  259               if (currentXid != null && currentXid.equals(xid))
  260               {
  261                  inManagedTransaction = false;
  262                  currentXid = null;
  263               }
  264            }
  265         }
  266         finally
  267         {
  268            unlock();
  269         }
  270      }
  271   
  272      public int prepare(Xid xid) throws XAException
  273      {
  274         lock();
  275         try
  276         {
  277            return xaResource.prepare(xid);
  278         }
  279         finally
  280         {
  281            unlock();
  282         }
  283      }
  284   
  285      public void commit(Xid xid, boolean onePhase) throws XAException
  286      {
  287         lock();
  288         try
  289         {
  290            xaResource.commit(xid, onePhase);
  291         }
  292         finally
  293         {
  294            unlock();
  295         }
  296      }
  297   
  298      public void rollback(Xid xid) throws XAException
  299      {
  300         lock();
  301         try
  302         {
  303            xaResource.rollback(xid);
  304         }
  305         finally
  306         {
  307            unlock();
  308         }
  309      }
  310   
  311      public void forget(Xid xid) throws XAException
  312      {
  313         xaResource.forget(xid);
  314      }
  315   
  316      public Xid[] recover(int flag) throws XAException
  317      {
  318         return xaResource.recover(flag);
  319      }
  320   
  321      public boolean isSameRM(XAResource other) throws XAException
  322      {
  323         Boolean overrideValue = ((XAManagedConnectionFactory) mcf).getIsSameRMOverrideValue();
  324         if (overrideValue != null)
  325         {
  326            return overrideValue.booleanValue();
  327         }
  328   
  329         // compare apples to apples
  330         return (other instanceof XAManagedConnection)
  331               ? xaResource.isSameRM(((XAManagedConnection) other).xaResource)
  332               : xaResource.isSameRM(other);
  333      }
  334   
  335      public int getTransactionTimeout() throws XAException
  336      {
  337         return xaResource.getTransactionTimeout();
  338      }
  339   
  340      public boolean setTransactionTimeout(int seconds) throws XAException
  341      {
  342         return xaResource.setTransactionTimeout(seconds);
  343      }
  344      
  345      private boolean isFailedXA(int errorCode)
  346      {
  347         
  348         return (errorCode == XAException.XAER_RMERR || errorCode == XAException.XAER_RMFAIL);      
  349      }
  350   }

Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.resource.adapter » jdbc » xa » [javadoc | source]