1 10 11 package org.mule.util.xa; 12 13 import org.apache.commons.logging.Log; 14 import org.apache.commons.logging.LogFactory; 15 16 import javax.transaction.Status ; 17 import javax.transaction.xa.XAException ; 18 import javax.transaction.xa.XAResource ; 19 import javax.transaction.xa.Xid ; 20 21 27 public class DefaultXASession implements XAResource 28 { 29 30 33 protected transient Log logger = LogFactory.getLog(getClass()); 34 35 protected AbstractTransactionContext localContext; 36 protected Xid localXid; 37 protected AbstractXAResourceManager resourceManager; 38 39 public DefaultXASession(AbstractXAResourceManager resourceManager) 40 { 41 this.localContext = null; 42 this.localXid = null; 43 this.resourceManager = resourceManager; 44 } 45 46 public XAResource getXAResource() 47 { 48 return this; 49 } 50 51 public Object getResourceManager() 52 { 53 return resourceManager; 54 } 55 56 public void begin() throws ResourceManagerException 60 { 61 if (localXid != null) 62 { 63 throw new IllegalStateException ( 64 "Cannot start local transaction. An XA transaction is already in progress."); 65 } 66 if (localContext != null) 67 { 68 throw new IllegalStateException ( 69 "Cannot start local transaction. A local transaction already in progress."); 70 } 71 localContext = resourceManager.createTransactionContext(this); 72 resourceManager.beginTransaction(localContext); 73 } 74 75 public void commit() throws ResourceManagerException 76 { 77 if (localXid != null) 78 { 79 throw new IllegalStateException ( 80 "Cannot commit local transaction as an XA transaction is in progress."); 81 } 82 if (localContext == null) 83 { 84 throw new IllegalStateException ("Cannot commit local transaction as no transaction was begun"); 85 } 86 resourceManager.commitTransaction(localContext); 87 localContext = null; 88 } 89 90 public void rollback() throws ResourceManagerException 91 { 92 if (localXid != null) 93 { 94 throw new IllegalStateException ( 95 "Cannot rollback local transaction as an XA transaction is in progress."); 96 } 97 if (localContext == null) 98 { 99 throw new IllegalStateException ("Cannot commit local transaction as no transaction was begun"); 100 } 101 resourceManager.rollbackTransaction(localContext); 102 localContext = null; 103 } 104 105 109 public boolean isSameRM(XAResource xares) throws XAException 110 { 111 return xares instanceof DefaultXASession 112 && ((DefaultXASession)xares).getResourceManager().equals(resourceManager); 113 } 114 115 public Xid [] recover(int flag) throws XAException 116 { 117 return null; 118 } 119 120 public void start(Xid xid, int flags) throws XAException 121 { 122 if (logger.isDebugEnabled()) 123 { 124 logger.debug(new StringBuffer (128).append("Thread ").append(Thread.currentThread()).append( 125 flags == TMNOFLAGS ? " starts" : flags == TMJOIN ? " joins" : " resumes").append( 126 " work on behalf of transaction branch ").append(xid).toString()); 127 } 128 if (this.localContext != null) 130 { 131 throw new XAException (XAException.XAER_PROTO); 132 } 133 if (this.localXid != null) 135 { 136 throw new XAException (XAException.XAER_PROTO); 137 } 138 switch (flags) 139 { 140 case TMNOFLAGS : 142 case TMJOIN : 143 default : 144 try 145 { 146 localContext = resourceManager.createTransactionContext(this); 147 resourceManager.beginTransaction(localContext); 148 } 149 catch (Exception e) 150 { 151 logger.error("Could not create new transactional resource", e); 152 throw new XAException (e.getMessage()); 153 } 154 break; 155 case TMRESUME : 156 localContext = resourceManager.getSuspendedTransactionalResource(xid); 157 if (localContext == null) 158 { 159 throw new XAException (XAException.XAER_NOTA); 160 } 161 resourceManager.removeSuspendedTransactionalResource(xid); 163 break; 164 } 165 localXid = xid; 166 resourceManager.addActiveTransactionalResource(localXid, localContext); 167 } 168 169 public void end(Xid xid, int flags) throws XAException 170 { 171 if (logger.isDebugEnabled()) 172 { 173 logger.debug(new StringBuffer (128).append("Thread ").append(Thread.currentThread()).append( 174 flags == TMSUSPEND ? " suspends" : flags == TMFAIL ? " fails" : " ends").append( 175 " work on behalf of transaction branch ").append(xid).toString()); 176 } 177 if (localContext == null) 179 { 180 throw new XAException (XAException.XAER_NOTA); 181 } 182 if (localXid == null || !localXid.equals(xid)) 184 { 185 throw new XAException (XAException.XAER_PROTO); 186 } 187 188 try 189 { 190 switch (flags) 191 { 192 case TMSUSPEND : 193 resourceManager.addSuspendedTransactionalResource(localXid, localContext); 195 resourceManager.removeActiveTransactionalResource(localXid); 196 break; 197 case TMFAIL : 198 resourceManager.setTransactionRollbackOnly(localContext); 199 break; 200 case TMSUCCESS : 201 break; 202 } 203 } 204 catch (ResourceManagerException e) 205 { 206 throw (XAException )new XAException (XAException.XAER_RMERR).initCause(e); 207 } 208 localXid = null; 209 localContext = null; 210 } 211 212 public void commit(Xid xid, boolean onePhase) throws XAException 213 { 214 if (xid == null) 215 { 216 throw new XAException (XAException.XAER_PROTO); 217 } 218 AbstractTransactionContext context = resourceManager.getActiveTransactionalResource(xid); 219 if (context == null) 220 { 221 throw new XAException (XAException.XAER_NOTA); 222 } 223 if (logger.isDebugEnabled()) 224 { 225 logger.debug("Committing transaction branch " + xid); 226 } 227 if (context.status == Status.STATUS_MARKED_ROLLBACK) 228 { 229 throw new XAException (XAException.XA_RBROLLBACK); 230 } 231 232 try 233 { 234 if (context.status != Status.STATUS_PREPARED) 235 { 236 if (onePhase) 237 { 238 resourceManager.prepareTransaction(context); 239 } 240 else 241 { 242 throw new XAException (XAException.XAER_PROTO); 243 } 244 } 245 resourceManager.commitTransaction(context); 246 } 247 catch (ResourceManagerException e) 248 { 249 throw (XAException )new XAException (XAException.XAER_RMERR).initCause(e); 250 } 251 resourceManager.removeActiveTransactionalResource(xid); 252 resourceManager.removeSuspendedTransactionalResource(xid); 253 } 254 255 public void rollback(Xid xid) throws XAException 256 { 257 if (xid == null) 258 { 259 throw new XAException (XAException.XAER_PROTO); 260 } 261 AbstractTransactionContext context = resourceManager.getActiveTransactionalResource(xid); 262 if (context == null) 263 { 264 throw new XAException (XAException.XAER_NOTA); 265 } 266 if (logger.isDebugEnabled()) 267 { 268 logger.debug("Rolling back transaction branch " + xid); 269 } 270 try 271 { 272 resourceManager.rollbackTransaction(context); 273 } 274 catch (ResourceManagerException e) 275 { 276 throw (XAException )new XAException (XAException.XAER_RMERR).initCause(e); 277 } 278 resourceManager.removeActiveTransactionalResource(xid); 279 resourceManager.removeSuspendedTransactionalResource(xid); 280 } 281 282 public int prepare(Xid xid) throws XAException 283 { 284 if (xid == null) 285 { 286 throw new XAException (XAException.XAER_PROTO); 287 } 288 289 AbstractTransactionContext context = resourceManager.getTransactionalResource(xid); 290 if (context == null) 291 { 292 throw new XAException (XAException.XAER_NOTA); 293 } 294 295 if (logger.isDebugEnabled()) 296 { 297 logger.debug("Preparing transaction branch " + xid); 298 } 299 300 if (context.status == Status.STATUS_MARKED_ROLLBACK) 301 { 302 throw new XAException (XAException.XA_RBROLLBACK); 303 } 304 305 try 306 { 307 return resourceManager.prepareTransaction(context); 308 } 309 catch (ResourceManagerException e) 310 { 311 throw (XAException )new XAException (XAException.XAER_RMERR).initCause(e); 312 } 313 } 314 315 public void forget(Xid xid) throws XAException 316 { 317 if (logger.isDebugEnabled()) 318 { 319 logger.debug("Forgetting transaction branch " + xid); 320 } 321 AbstractTransactionContext context = resourceManager.getTransactionalResource(xid); 322 if (context == null) 323 { 324 throw new XAException (XAException.XAER_NOTA); 325 } 326 resourceManager.removeActiveTransactionalResource(xid); 327 resourceManager.removeSuspendedTransactionalResource(xid); 328 } 329 330 335 public int getTransactionTimeout() throws XAException 336 { 337 return (int)(resourceManager.getDefaultTransactionTimeout() / 1000); 338 } 339 340 345 public boolean setTransactionTimeout(int timeout) throws XAException 346 { 347 resourceManager.setDefaultTransactionTimeout(timeout * 1000); 348 return false; 349 } 350 351 } 352 | Popular Tags |