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
00027 package org.objectweb.jonas.jdbc_xa;
00028
00029 import java.sql.Connection;
00030 import java.sql.SQLException;
00031 import javax.transaction.xa.*;
00032 import org.objectweb.jonas.common.Log;
00033 import org.objectweb.util.monolog.api.Logger;
00034 import org.objectweb.util.monolog.api.BasicLevel;
00035
00049 public class XAResourceImpl implements XAResource {
00050
00051 private static Logger logger = null;
00052
00053 private Connection actConn = null;
00054 private XAConnectionImpl xac = null;
00055 private int timeout;
00056 private Xid currXid = null;
00057 private boolean xaStarted = false;
00058 private String rmid = null;
00059
00060
00061
00062
00063
00070 public XAResourceImpl(XAConnectionImpl xac, Connection actual, XADataSourceImpl ds) {
00071 this.xac = xac;
00072 this.actConn = actual;
00073 this.rmid = ds.getDataSourceName();
00074 logger = Log.getLogger(Log.JONAS_JDBCXA_PREFIX);
00075 logger.log(BasicLevel.DEBUG, "new object for " + this);
00076 }
00077
00078
00079
00080
00081
00088 public synchronized void commit(Xid xid, boolean onePhase) throws XAException {
00089
00090 logger.log(BasicLevel.DEBUG, "XA-COMMIT for " + this);
00091 logger.log(BasicLevel.DEBUG, "Xid = " + xid);
00092
00093
00094
00095
00096 if (currXid != null && !currXid.equals(xid)) {
00097 logger.log(BasicLevel.DEBUG, "mixed xids: " + xid + " != " + currXid);
00098 XAException ex = new XAException("cannot mix transactions");
00099 throw(ex);
00100 }
00101 currXid = null;
00102 if (xaStarted) {
00103
00104
00105
00106 logger.log(BasicLevel.WARN, "XA START without XA END");
00107
00108 xaStarted = false;
00109 }
00110
00111
00112 try {
00113 actConn.commit();
00114 } catch (SQLException e) {
00115 logger.log(BasicLevel.ERROR, "Cannot commit transaction:" + e);
00116 xac.notifyError(e);
00117 throw(new XAException("Error on commit"));
00118 }
00119 }
00120
00127 public synchronized void end(Xid xid, int flags) throws XAException {
00128
00129 logger.log(BasicLevel.DEBUG, "XA-END for " + this);
00130 logger.log(BasicLevel.DEBUG, "Xid = " + xid);
00131
00132
00133 if (currXid == null || !currXid.equals(xid)) {
00134 logger.log(BasicLevel.WARN, "END without START or mixed xids: " + xid + " != " + currXid);
00135 XAException ex = new XAException(XAException.XA_RBPROTO);
00136 throw(ex);
00137 }
00138 xaStarted = false;
00139 }
00140
00147 public synchronized void forget(Xid xid) throws XAException {
00148
00149
00150 logger.log(BasicLevel.DEBUG, "XA-FORGET for " + this);
00151 logger.log(BasicLevel.DEBUG, "Xid = " + xid);
00152 currXid = null;
00153 }
00154
00161 public synchronized int getTransactionTimeout() throws XAException {
00162 logger.log(BasicLevel.DEBUG, "getTransactionTimeout for " + this);
00163 return timeout;
00164 }
00165
00173 public boolean isSameRM(XAResource xares) throws XAException {
00174
00175
00176
00177
00178
00179
00180
00181 if (xares.equals(this)) {
00182 logger.log(BasicLevel.DEBUG, "isSameRM = true " + this);
00183 return true;
00184 }
00185 logger.log(BasicLevel.DEBUG, "isSameRM = false " + this);
00186 return false;
00187 }
00188
00189
00196 public synchronized int prepare(Xid xid) throws XAException {
00197
00198 logger.log(BasicLevel.DEBUG, "XA-PREPARE for " + this);
00199 logger.log(BasicLevel.DEBUG, "Xid = " + xid);
00200
00201 return XA_OK;
00202 }
00203
00210 public synchronized Xid[] recover(int flag) throws XAException {
00211
00212 logger.log(BasicLevel.DEBUG, "XA-RECOVER for " + this);
00213
00214 return null;
00215 }
00216
00223 public synchronized void rollback(Xid xid) throws XAException {
00224
00225 logger.log(BasicLevel.DEBUG, "XA-ROLLBACK for " + this);
00226 logger.log(BasicLevel.DEBUG, "Xid = " + xid);
00227
00228
00229
00230
00231 if (currXid != null && !currXid.equals(xid)) {
00232 logger.log(BasicLevel.DEBUG, "mixed xids: " + xid + " != " + currXid);
00233 XAException ex = new XAException("Cannot mix transactions");
00234 throw(ex);
00235 }
00236 currXid = null;
00237 if (xaStarted) {
00238
00239
00240
00241 logger.log(BasicLevel.WARN, "XA START without XA END");
00242 xaStarted = false;
00243 }
00244
00245
00246 try {
00247 if (actConn.getAutoCommit() == true) {
00248 logger.log(BasicLevel.ERROR, "Rollback called on XAResource with AutoCommit set");
00249 throw (new XAException(XAException.XA_HEURCOM));
00250 }
00251 } catch (SQLException e) {
00252 logger.log(BasicLevel.ERROR, "Cannot getAutoCommit:" + e);
00253 xac.notifyError(e);
00254 throw(new XAException("Error on getAutoCommit"));
00255 }
00256
00257
00258 try {
00259 actConn.rollback();
00260 } catch (SQLException e) {
00261 logger.log(BasicLevel.ERROR, "Cannot rollback transaction:" + e);
00262 xac.notifyError(e);
00263 throw(new XAException("Error on rollback"));
00264 }
00265 }
00266
00274 public synchronized boolean setTransactionTimeout(int seconds) throws XAException {
00275
00276 logger.log(BasicLevel.DEBUG, "setTransactionTimeout " + this);
00277 timeout = seconds;
00278 return true;
00279 }
00280
00286 public synchronized void start(Xid xid, int flags) throws XAException {
00287
00288 logger.log(BasicLevel.DEBUG, "XA-START for " + this);
00289 logger.log(BasicLevel.DEBUG, "Xid = " + xid);
00290 if (xaStarted) {
00291 logger.log(BasicLevel.DEBUG, "mixed xids: " + xid + " != " + currXid);
00292 XAException ex = new XAException("XA START: mixed transactions");
00293 throw ex;
00294 }
00295 currXid = xid;
00296 xaStarted = true;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 public String getRMID() {
00308 return rmid;
00309 }
00310 }