XAResourceImpl.java

00001  /*
00002  * JOnAS: Java(TM) Open Application Server
00003  * Copyright (C) 1999 Bull S.A.
00004  * Contact: jonas-team@objectweb.org
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00019  * USA
00020  *
00021  * Initial developer(s): Eric HARDESTY
00022  * --------------------------------------------------------------------------
00023  * $Id: XAResourceImpl.java,v 1.7 2004/10/29 23:33:37 ehardesty Exp $
00024  * --------------------------------------------------------------------------
00025  */
00026 package org.objectweb.jonas.jdbc;
00027 
00028 import java.sql.SQLException;
00029 
00030 import javax.resource.spi.ConnectionEvent;
00031 import javax.transaction.xa.XAException;
00032 import javax.transaction.xa.XAResource;
00033 import javax.transaction.xa.Xid;
00034 
00035 import org.objectweb.util.monolog.api.BasicLevel;
00036 
00043 public class XAResourceImpl implements XAResource {
00044 
00045     // Current Xid
00046     private Xid currentXid = null;
00047 
00048     // Is a xa transaction started ?
00049     boolean started = false;
00050     boolean ended = true;
00051 
00052     protected ManagedConnectionImpl mc = null;
00053     private XAResource xares = null;
00054 
00060     public XAResourceImpl(ManagedConnectionImpl mc, XAResource xares) {
00061         this.mc = mc;
00062         this.xares = xares;
00063     }
00064 
00068     public void commit(Xid xid, boolean onePhase) throws XAException {
00069         mc.trace.log(BasicLevel.DEBUG, "" + xid + "," + onePhase);
00070 
00071         // Commit the transaction
00072         try {
00073             if (xares != null) {
00074                 xares.commit(xid, onePhase);
00075                 if (xid.equals(currentXid)) {
00076                     started = false;
00077                 }
00078             } else {
00079                 // Make sure that this call is for the XID
00080                 if (currentXid == null || !currentXid.equals(xid) || !started) {
00081                     mc.trace.log(BasicLevel.ERROR, "passed xid(" + xid
00082                                                    + "),current Xid("
00083                                                    + currentXid
00084                                                    + "),started(" + started + ")");
00085                     throw new XAException("Commit: Must call correct XAResource for its started XID");
00086                 }
00087                 mc.connection.commit();
00088                 started = false;
00089             }
00090         } catch (XAException xe) {
00091             mc.trace.log(BasicLevel.ERROR, xe.getMessage());
00092             throw xe;
00093         } catch (SQLException e) {
00094             mc.trace.log(BasicLevel.ERROR, e.getMessage());
00095             try {
00096                 mc.signalEvent(ConnectionEvent.CONNECTION_ERROR_OCCURRED, null, e);
00097             } catch (Exception ex) {}
00098             throw new XAException("Error on commit");
00099         }
00100 
00101         try {
00102             if (!mc.connection.getAutoCommit()) {
00103                 mc.connection.setAutoCommit(true);
00104             }
00105         } catch (Exception exc) {
00106             if (xares == null) {
00107                 mc.trace.log(BasicLevel.DEBUG,
00108                     "Unable to set autoCommit to true:" + exc.getMessage());
00109             }
00110         }
00111     }
00112 
00116     public void end(Xid xid, int flags) throws XAException {
00117         mc.trace.log(BasicLevel.DEBUG, "" + xid + "," + flags);
00118         // Make sure that the Xid has started
00119         if (currentXid == null || !currentXid.equals(xid)) {
00120             throw new XAException(XAException.XA_RBPROTO);
00121         }
00122         if (!started && ended) {
00123             throw new XAException(XAException.XA_RBPROTO);
00124         }
00125         ended = true;
00126         if (xares != null) {
00127             xares.end(xid, flags);
00128         }
00129     }
00130 
00134     public void forget(Xid xid) throws XAException {
00135         mc.trace.log(BasicLevel.DEBUG, "" + xid);
00136         if (xares != null) {
00137             xares.forget(xid);
00138         }
00139     }
00140 
00144     public int getTransactionTimeout() throws XAException { 
00145         if (xares != null) {
00146             return xares.getTransactionTimeout();
00147         }
00148         return 0;
00149     }
00150 
00155     public boolean isSameRM(XAResource xaRes) throws XAException {
00156 
00157         boolean ret = false;
00158         if (xaRes.equals(this)) {
00159             ret = true;
00160         } else if (!(xaRes instanceof XAResourceImpl)) {
00161             ret = false;
00162         } else {
00163             XAResourceImpl xaResImpl = (XAResourceImpl) xaRes;
00164             if (mc == xaResImpl.mc) {
00165                 ret = true;
00166             }
00167         }
00168         mc.trace.log(BasicLevel.DEBUG, "" + xaRes + "," + this + " is " + ret);
00169         return ret;
00170     }
00171 
00175     public int prepare(Xid xid) throws XAException {
00176         mc.trace.log(BasicLevel.DEBUG, "" + xid);
00177         if (xares != null) {
00178             int ret = xares.prepare(xid);
00179             // If read-only, then do what would have been done in the commit call
00180             if (ret == XA_RDONLY) {
00181                 started = false;
00182                 try {
00183                     if (!mc.connection.getAutoCommit()) {
00184                         mc.connection.setAutoCommit(true);
00185                     }
00186                 } catch (Exception exc) { }
00187             }
00188             return ret;
00189         }
00190         // Just return true, since we are just simulating XA with our wrapper
00191         return XA_OK;
00192     }
00193 
00197     public Xid[] recover(int flag) throws XAException {
00198         mc.trace.log(BasicLevel.DEBUG, "" + flag);
00199         if (xares != null) {
00200             return xares.recover(flag);
00201         }
00202         // Not a full RM, so just return null
00203         return null;
00204     }
00205 
00209     public void rollback(Xid xid) throws XAException {
00210         mc.trace.log(BasicLevel.DEBUG, "" + xid);
00211 
00212         // Rollback the Xid
00213         try {
00214             if (xares != null) {
00215                 xares.rollback(xid);
00216                 if (xid.equals(currentXid)) {
00217                     started = false;
00218                 }
00219             } else {
00220                 // Make sure that this call is for the XID
00221                 if (currentXid == null || !currentXid.equals(xid) || !started) {
00222                     mc.trace.log(BasicLevel.ERROR, "passed xid(" + xid
00223                                      + "),current Xid(" + currentXid
00224                                      + "),started(" + started + ")");
00225                     throw new XAException("Rollback: Must call correct XAResource for its started XID");
00226                 }
00227                 mc.connection.rollback();
00228                 started = false;
00229             }
00230         } catch (XAException xe) {
00231             mc.trace.log(BasicLevel.ERROR, xe.getMessage());
00232             throw xe;
00233         } catch (SQLException e) {
00234             try {
00235                 mc.trace.log(BasicLevel.ERROR, e.getMessage());
00236                 mc.signalEvent(
00237                     ConnectionEvent.CONNECTION_ERROR_OCCURRED, null, e);
00238             } catch (Exception ex) {}
00239             throw(new XAException("Error on rollback"));
00240         }
00241         try {
00242             if (!mc.connection.getAutoCommit()) {
00243                 mc.connection.setAutoCommit(true);
00244             }
00245         } catch (Exception exc) {
00246             if (xares == null) {
00247                 mc.trace.log(BasicLevel.DEBUG,
00248                     "Unable to set autoCommit to true:" + exc.getMessage());
00249             }
00250         }
00251     }
00252 
00256     public boolean setTransactionTimeout(int seconds) throws XAException {
00257         if (xares != null) {
00258             return xares.setTransactionTimeout(seconds);
00259         }
00260         return false;
00261     }
00262 
00267     public void start(Xid xid, int flags) throws XAException {
00268         mc.trace.log(BasicLevel.DEBUG, "" + xid + "," + flags);
00269         if (started && (currentXid == null || !currentXid.equals(xid))) {
00270             mc.trace.log(BasicLevel.ERROR,
00271                 "Must call correct XAResource for its started XID");
00272             throw new XAException("XAResourceImpl.start : Must call correct XAResource for its started XID");
00273         }
00274         currentXid = xid;
00275         started = true;
00276         ended = false;
00277         try {
00278             if (mc.connection.getAutoCommit()) {
00279                 mc.connection.setAutoCommit(false);
00280             }
00281         } catch (Exception ex) {
00282             ex.printStackTrace();
00283             mc.trace.log(BasicLevel.ERROR,
00284                 "Unable to set autoCommit to false:" + ex.getMessage());
00285             throw(new XAException(
00286                 "Error : Unable to set autoCommit to false in start"));
00287         }
00288         if (xares != null) {
00289             xares.start(xid, flags);
00290         }
00291     }
00292 }

Generated on Tue Feb 15 15:05:16 2005 for JOnAS by  doxygen 1.3.9.1