00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00046 private Xid currentXid = null;
00047
00048
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
00072 try {
00073 if (xares != null) {
00074 xares.commit(xid, onePhase);
00075 if (xid.equals(currentXid)) {
00076 started = false;
00077 }
00078 } else {
00079
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
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
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
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
00203 return null;
00204 }
00205
00209 public void rollback(Xid xid) throws XAException {
00210 mc.trace.log(BasicLevel.DEBUG, "" + xid);
00211
00212
00213 try {
00214 if (xares != null) {
00215 xares.rollback(xid);
00216 if (xid.equals(currentXid)) {
00217 started = false;
00218 }
00219 } else {
00220
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 }