1 23 24 package org.apache.slide.common; 25 26 import java.util.Hashtable ; 27 import java.util.Vector ; 28 29 import javax.transaction.xa.XAException ; 30 import javax.transaction.xa.XAResource ; 31 import javax.transaction.xa.Xid ; 32 33 import org.apache.slide.transaction.SlideTransactionManager; 34 35 41 public abstract class AbstractService extends AbstractServiceBase 42 implements Service { 43 44 45 47 48 public static final int TX_IDLE = 0; 49 public static final int TX_PREPARED = 1; 50 public static final int TX_SUSPENDED = 2; 51 52 53 55 56 59 protected Hashtable currentContexts = new Hashtable (); 60 61 62 64 65 79 public void commit(Xid xid, boolean onePhase) 80 throws XAException { 81 82 ContextTuple currentContextTuple = 83 (ContextTuple) currentContexts.get(Thread.currentThread()); 84 Xid currentContext = 85 currentContextTuple!=null?currentContextTuple.getXid():null; 86 87 if (currentContext == null) 88 throw new XAException (XAException.XAER_NOTA); 89 if (xid == null) 90 throw new XAException (XAException.XAER_INVAL); 91 if (currentContext.getGlobalTransactionId() 92 != xid.getGlobalTransactionId()) 93 throw new XAException (XAException.XAER_PROTO); 94 95 if (!onePhase && currentContextTuple.getStatus() != TX_PREPARED) 96 throw new XAException (XAException.XAER_PROTO); 97 if (onePhase && 98 (!((currentContextTuple.getStatus() == TX_IDLE) || 99 (currentContextTuple.getStatus() == TX_SUSPENDED)))) 100 throw new XAException (XAException.XAER_PROTO); 101 102 if (((ContextTuple) currentContexts.get(Thread.currentThread())) 103 .getRollbackOnly()) { 104 rollback(xid); 105 throw new XAException (XAException.XA_RBROLLBACK); 106 } 107 108 currentContexts.remove(Thread.currentThread()); 109 110 } 111 112 113 132 public void end(Xid xid, int flags) 133 throws XAException { 134 135 ContextTuple currentContextTuple = 136 (ContextTuple) currentContexts.get(Thread.currentThread()); 137 Xid currentContext = 138 currentContextTuple!=null?currentContextTuple.getXid():null; 139 140 if (currentContext == null) 141 throw new XAException (XAException.XAER_NOTA); 142 if (xid == null) 143 throw new XAException (XAException.XAER_INVAL); 144 if (currentContext.getGlobalTransactionId() 145 != xid.getGlobalTransactionId()) 146 throw new XAException (XAException.XAER_PROTO); 147 148 if (flags == XAResource.TMSUSPEND) 149 currentContextTuple.setStatus(TX_SUSPENDED); 150 151 if (flags == XAResource.TMFAIL) 152 ((ContextTuple) currentContexts.get(Thread.currentThread())) 153 .setRollbackOnly(true); 154 155 } 156 157 158 166 public void forget(Xid xid) 167 throws XAException { 168 169 ContextTuple currentContextTuple = 170 (ContextTuple) currentContexts.get(Thread.currentThread()); 171 Xid currentContext = 172 currentContextTuple!=null?currentContextTuple.getXid():null; 173 174 if (currentContext == null) 175 throw new XAException (XAException.XAER_NOTA); 176 if (xid == null) 177 throw new XAException (XAException.XAER_INVAL); 178 if (currentContext.getGlobalTransactionId() 179 != xid.getGlobalTransactionId()) 180 throw new XAException (XAException.XAER_PROTO); 181 182 currentContexts.remove(Thread.currentThread()); 183 184 } 185 186 187 198 public int getTransactionTimeout() 199 throws XAException { 200 201 return ((ContextTuple) currentContexts.get(Thread.currentThread())) 202 .getTransactionTimeout(); 203 204 } 205 206 207 218 public boolean isSameRM(XAResource xares) 219 throws XAException { 220 221 if (xares == null) 222 return false; 223 224 return (this == xares); 225 226 } 227 228 229 242 public int prepare(Xid xid) 243 throws XAException { 244 245 ContextTuple currentContextTuple = 246 (ContextTuple) currentContexts.get(Thread.currentThread()); 247 Xid currentContext = 248 currentContextTuple!=null?currentContextTuple.getXid():null; 249 250 if (currentContext == null) 251 throw new XAException (XAException.XAER_NOTA); 252 if (xid == null) 253 throw new XAException (XAException.XAER_INVAL); 254 if (currentContext.getGlobalTransactionId() 255 != xid.getGlobalTransactionId()) 256 throw new XAException (XAException.XAER_PROTO); 257 258 if (!((currentContextTuple.getStatus() == TX_IDLE) || 259 (currentContextTuple.getStatus() == TX_SUSPENDED))) 260 throw new XAException (XAException.XAER_PROTO); 261 262 if (((ContextTuple) currentContexts.get(Thread.currentThread())) 263 .getRollbackOnly()) { 264 throw new XAException (XAException.XA_RBROLLBACK); 267 } 268 269 currentContextTuple.setStatus(TX_PREPARED); 270 271 return XAResource.XA_OK; 272 273 } 274 275 276 291 public Xid [] recover(int flag) 292 throws XAException { 293 294 ContextTuple currentContextTuple = 295 (ContextTuple) currentContexts.get(Thread.currentThread()); 296 Xid currentContext = 297 currentContextTuple!=null?currentContextTuple.getXid():null; 298 299 Vector list = new Vector (); 300 301 if ((currentContextTuple.getStatus() == TX_PREPARED) && 302 (currentContext != null)) 303 list.addElement(currentContext); 304 305 return (Xid []) list.toArray(new Xid [list.size()]); 306 307 } 308 309 310 317 public void rollback(Xid xid) 318 throws XAException { 319 320 ContextTuple currentContextTuple = 321 (ContextTuple) currentContexts.get(Thread.currentThread()); 322 Xid currentContext = 323 currentContextTuple!=null?currentContextTuple.getXid():null; 324 325 if (currentContext == null) 326 throw new XAException (XAException.XAER_NOTA); 327 if (xid == null) 328 throw new XAException (XAException.XAER_INVAL); 329 if (currentContext.getGlobalTransactionId() 330 != xid.getGlobalTransactionId()) 331 throw new XAException (XAException.XAER_PROTO); 332 333 currentContexts.remove(Thread.currentThread()); 334 335 } 336 337 338 347 public boolean setTransactionTimeout(int seconds) 348 throws XAException { 349 350 ((ContextTuple) currentContexts.get(Thread.currentThread())) 351 .setTransactionTimeout(seconds); 352 return true; 353 354 } 355 356 357 373 public void start(Xid xid, int flags) 374 throws XAException { 375 376 ContextTuple currentContextTuple = 377 (ContextTuple) currentContexts.get(Thread.currentThread()); 378 Xid currentContext = 379 currentContextTuple!=null?currentContextTuple.getXid():null; 380 381 if (xid == null) 382 throw new XAException (XAException.XAER_INVAL); 383 if ( (currentContext != null) && 384 (currentContext.getGlobalTransactionId() 385 != xid.getGlobalTransactionId()) ) 386 throw new XAException (XAException.XAER_OUTSIDE); 387 388 switch (flags) { 389 case XAResource.TMNOFLAGS: 390 if (currentContext != null) 391 throw new XAException (XAException.XAER_INVAL); 392 currentContext = xid; 393 currentContexts.put 395 (Thread.currentThread(),new ContextTuple 396 (xid, TX_IDLE, 397 SlideTransactionManager.DEFAULT_TRANSACTION_TIMEOUT, 398 false)); 399 break; 400 case XAResource.TMJOIN: 401 if (currentContext == null) 402 throw new XAException (XAException.XAER_NOTA); 403 if (currentContext.getGlobalTransactionId() 404 != xid.getGlobalTransactionId()) 405 throw new XAException (XAException.XAER_INVAL); 406 break; 407 case XAResource.TMRESUME: 408 if (currentContext == null) 409 throw new XAException (XAException.XAER_NOTA); 410 if (currentContextTuple.getStatus() != TX_SUSPENDED) 411 throw new XAException (XAException.XAER_INVAL); 412 currentContextTuple.setStatus(TX_IDLE); 413 break; 414 } 415 416 } 417 418 419 421 422 425 private class ContextTuple { 426 private Xid xid; 427 private int status; 428 private int transactionTimeout; 429 private boolean rollbackOnly; 430 public ContextTuple(Xid xid, int status, int transactionTimeout, 431 boolean rollbackOnly) { 432 this.xid = xid; 433 setStatus(status); 434 setTransactionTimeout(transactionTimeout); 435 setRollbackOnly(rollbackOnly); 436 } 437 public Xid getXid() { 438 return xid; 439 } 440 public int getStatus() { 441 return status; 442 } 443 public void setStatus(int status) { 444 this.status = status; 445 } 446 public int getTransactionTimeout() { 447 return transactionTimeout; 448 } 449 public void setTransactionTimeout(int transactionTimeout) { 450 this.transactionTimeout = transactionTimeout; 451 } 452 public boolean getRollbackOnly() { 453 return rollbackOnly; 454 } 455 public void setRollbackOnly(boolean rollbackOnly) { 456 this.rollbackOnly = rollbackOnly; 457 } 458 459 } 460 461 462 } 463 464 465 | Popular Tags |