1 23 24 28 29 package com.sun.jts.jta; 30 31 import java.util.*; 32 import javax.transaction.xa.*; 33 import javax.transaction.*; 34 import org.omg.CosTransactions.*; 35 import com.sun.jts.jta.NativeXAResource; 36 import com.sun.jts.jtsxa.XID; 37 import com.sun.jts.jtsxa.OTSResource; 38 import com.sun.jts.jtsxa.OTSResourceImpl; 39 import javax.transaction.SystemException ; 40 import javax.transaction.RollbackException ; 41 import javax.transaction.Synchronization ; 42 import com.sun.jts.jtsxa.Utility; 43 import com.sun.jts.CosTransactions.Configuration; 44 import com.sun.jts.CosTransactions.ControlImpl; 45 import com.sun.jts.CosTransactions.TopCoordinator; 46 import org.omg.CORBA.TRANSACTION_ROLLEDBACK ; 47 import com.sun.jts.CosTransactions.GlobalTID; 48 49 50 import java.util.logging.Logger ; 51 import java.util.logging.Level ; 52 import com.sun.logging.LogDomains; 53 import com.sun.jts.utils.LogFormatter; 54 59 public class TransactionState { 60 61 64 private static final int NOT_EXIST = -1; 65 private static final int ASSOCIATED = 0; 66 private static final int NOT_ASSOCIATED = 1; 67 private static final int ASSOCIATION_SUSPENDED = 2; 68 private static final int FAILED = 3; 69 private static final int ROLLING_BACK = 4; 70 71 private static final Integer NOT_EXIST_INTEGER = new Integer (NOT_EXIST); 72 private static final Integer ASSOCIATED_INTEGER = new Integer (ASSOCIATED); 73 private static final Integer NOT_ASSOCIATED_INTEGER = new Integer (NOT_ASSOCIATED); 74 private static final Integer ASSOCIATION_SUSPENDED_INTEGER = new Integer (ASSOCIATION_SUSPENDED); 75 private static final Integer FAILED_INTEGER = new Integer (FAILED); 76 private static final Integer ROLLING_BACK_INTEGER = new Integer (ROLLING_BACK); 77 78 82 private Map resourceStates; 83 84 87 private Map resourceList; 88 89 92 private Set seenXids; 93 94 98 private List factories; 99 100 private SynchronizationImpl syncImpl; 102 103 106 private GlobalTID gtid; 107 private TransactionImpl tran; 108 111 112 static Logger _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER); 113 114 public static boolean debug = false; 115 117 public TransactionState(GlobalTID gtid, TransactionImpl tran) { 118 resourceStates = new HashMap(); 119 resourceList = new HashMap(); 120 seenXids = new HashSet(); 121 factories = new ArrayList(); 122 this.gtid = gtid; 123 this.tran = tran; 124 } 125 126 127 132 synchronized public void beforeCompletion() { 133 134 boolean exceptionThrown = false; 135 XAResource res = null; 136 Iterator e = resourceStates.keySet().iterator(); 137 while (e.hasNext()) { 138 try { 139 res = (XAResource) e.next(); 140 int XAState = getXAState(res); 141 switch (XAState) { 142 case NOT_ASSOCIATED: 143 case FAILED: 144 break; 145 case ASSOCIATION_SUSPENDED: 146 case ASSOCIATED: 147 Xid xid = (Xid) resourceList.get(res); 148 res.end(xid, XAResource.TMSUCCESS); 149 setXAState(res, NOT_ASSOCIATED_INTEGER); 150 break; 151 case ROLLING_BACK: 152 case NOT_EXIST: 153 default: 154 throw new IllegalStateException ("Wrong XA State: " + XAState); 155 } 156 } catch (Exception ex) { 157 setXAState(res, FAILED); 158 _logger.log(Level.WARNING,"jts.delist_exception",ex); 159 exceptionThrown = true; 160 } 161 } 162 if (exceptionThrown) { 163 try { 164 tran.setRollbackOnly(); 165 } catch (Exception ex) {} 166 } 167 } 168 169 172 synchronized public void rollback(XAResource res) 173 throws IllegalStateException , XAException { 174 175 Xid xid = (Xid) resourceList.get(res); 176 assert_prejdk14(xid != null); 177 int XAState = getXAState(res); 178 switch (XAState) { 179 case NOT_ASSOCIATED: 180 case FAILED: 181 res.rollback(xid); 182 break; 183 case ASSOCIATION_SUSPENDED: 184 res.end(xid, XAResource.TMSUCCESS); 185 setXAState(res, NOT_ASSOCIATED_INTEGER); 186 res.rollback(xid); 187 break; 188 case ASSOCIATED: 189 res.end(xid, XAResource.TMSUCCESS); 190 setXAState(res, NOT_ASSOCIATED_INTEGER); 191 res.rollback(xid); 192 197 break; 198 case ROLLING_BACK: 199 case NOT_EXIST: 200 default: 201 throw new IllegalStateException ("Wrong XAState: " + 202 XAState); 203 } 204 } 205 206 private Xid computeXid(XAResource res, Control control) 207 throws Inactive, Unavailable, XAException { 208 209 int size = factories.size(); 211 for (int i=0; i<size; i++) { 212 XAResource fac = (XAResource) factories.get(i); 213 if (res.isSameRM(fac)) { 214 Xid xid = (Xid) resourceList.get(fac); 216 return xid; 217 } 218 } 219 220 XID xid; 223 224 if( Configuration.isLocalFactory()) { 225 xid = Utility.getXID(((ControlImpl) control).get_localCoordinator()); 226 } else { 227 xid = Utility.getXID(control.get_coordinator()); 228 } 229 factories.add(res); 230 231 byte [] branchid = parseSize(size); 232 byte [] sname = Configuration.getServerNameByteArray(); 233 byte [] branch = new byte[sname.length+1+branchid.length]; 234 235 System.arraycopy(sname, 0, branch, 0, sname.length); 236 branch[sname.length] = (byte) ','; 237 System.arraycopy(branchid, 0, branch, sname.length+1, branchid.length); 238 239 xid.setBranchQualifier(branch); 240 241 return xid; 242 } 243 244 245 synchronized public void startAssociation(XAResource res, Control control, 246 int status) 247 throws XAException, SystemException , IllegalStateException , 248 RollbackException 249 { 250 OTSResource ref; 251 252 try { 253 Xid xid = null; 255 boolean newResource = false; 256 boolean seenXid = false; 257 if (resourceList.get(res) == null) { 258 if (status != 261 javax.transaction.Status.STATUS_ACTIVE) { 262 throw new RollbackException (); 263 } 264 265 newResource = true; 266 xid = computeXid(res, control); 267 seenXid = seenXids.contains(xid); 268 269 if (!seenXid) { 271 ref = new OTSResourceImpl(xid, res, this); 274 if( Configuration.isLocalFactory()) { 275 ((ControlImpl) control).get_localCoordinator().register_resource(ref); 276 } 277 else { 278 control.get_coordinator().register_resource(ref); 279 } 280 } 281 resourceList.put(res, xid); 282 } else { 283 xid = (Xid) resourceList.get(res); 285 seenXid = seenXids.contains(xid); 286 } 287 288 int XAState = getXAState(res); 289 if (!seenXid) { 290 seenXids.add(xid); 292 res.start(xid, XAResource.TMNOFLAGS); 293 setXAState(res, ASSOCIATED_INTEGER); 294 } else { 295 switch (XAState) { 297 case NOT_ASSOCIATED: 298 case NOT_EXIST: 299 res.start(xid, XAResource.TMJOIN); 300 setXAState(res, ASSOCIATED_INTEGER); 301 break; 302 case ASSOCIATION_SUSPENDED: 303 res.start(xid, XAResource.TMRESUME); 304 setXAState(res, ASSOCIATED_INTEGER); 305 break; 306 case ASSOCIATED: 307 case FAILED: 308 case ROLLING_BACK: 309 default: 310 throw new IllegalStateException ("Wrong XAState: " + 311 XAState); 312 } 313 } 314 315 323 } catch (XAException ex) { 324 setXAState(res, FAILED_INTEGER); 325 throw ex; 326 } catch (Inactive ex) { 327 _logger.log(Level.WARNING,"jts.transaction_inactive",ex); 328 throw new SystemException (); 329 } catch (Unavailable ex) { 330 _logger.log(Level.WARNING,"jts.object_unavailable",ex); 331 throw new SystemException (); 332 } 333 } 334 335 synchronized 336 public void endAssociation(XAResource xares, int flags) 337 throws XAException, IllegalStateException 338 { 339 try { 340 Xid xid = (Xid) resourceList.get(xares); 341 assert_prejdk14(xid != null); 342 int XAState = getXAState(xares); 343 switch (XAState) { 344 case ASSOCIATED: 345 if ((flags & XAResource.TMSUCCESS) != 0) { 346 xares.end(xid, XAResource.TMSUCCESS); 347 setXAState(xares, NOT_ASSOCIATED_INTEGER); 348 } else if ((flags & XAResource.TMSUSPEND) != 0) { 349 xares.end(xid, XAResource.TMSUSPEND); 350 setXAState(xares, ASSOCIATION_SUSPENDED_INTEGER); 351 } else { 352 xares.end(xid, XAResource.TMFAIL); 353 setXAState(xares, FAILED_INTEGER); 354 } 355 break; 356 case ROLLING_BACK: 357 xares.end(xid, XAResource.TMSUCCESS); 361 setXAState(xares, NOT_ASSOCIATED_INTEGER); 362 xares.rollback(xid); 363 364 break; 365 case ASSOCIATION_SUSPENDED: 366 if ((flags & XAResource.TMSUCCESS) != 0) { 367 xares.end(xid, XAResource.TMSUCCESS); 368 setXAState(xares, NOT_ASSOCIATED_INTEGER); 369 } else if ((flags & XAResource.TMSUSPEND) != 0) { 370 throw new IllegalStateException 371 ("Wrong XAState: " + XAState); 372 } else { 373 xares.end(xid, XAResource.TMFAIL); 374 setXAState(xares, FAILED_INTEGER); 375 } 376 break; 377 case NOT_ASSOCIATED: 378 case NOT_EXIST: 379 case FAILED: 380 default: 381 throw new IllegalStateException ("Wrong XAState: " + XAState); 382 } 383 } catch (XAException ex) { 384 setXAState(xares, FAILED_INTEGER); 385 throw ex; 386 } 387 } 388 389 void setRollbackOnly() 392 throws IllegalStateException , SystemException { 393 tran.setRollbackOnly(); 394 } 395 396 404 405 synchronized 406 public void registerSynchronization(Synchronization sync, 407 Control control, 408 boolean interposed) 409 throws RollbackException , IllegalStateException , 410 SystemException { 411 412 try { 413 if (syncImpl == null) { 415 syncImpl = new SynchronizationImpl(this); 417 418 if (Configuration.isLocalFactory()) { 421 ((ControlImpl) control).get_localCoordinator().register_synchronization(syncImpl); 422 } else { 423 control.get_coordinator().register_synchronization(syncImpl); 424 } 425 } 426 syncImpl.addSynchronization(sync, interposed); 427 } catch (TRANSACTION_ROLLEDBACK ex) { 428 throw new RollbackException (); 429 } catch (Unavailable ex) { 430 throw new SystemException (); 431 } catch (Inactive ex) { 432 throw new IllegalStateException (); 433 } catch (Exception ex) { 434 throw new SystemException (); 435 } 436 } 437 438 private void setXAState(XAResource res, Integer state) { 439 if (debug) { 440 int oldValue = getXAState(res); 441 _logger.log(Level.FINE,"transaction id : " + gtid); 442 _logger.log(Level.FINE,"res: " + res + "," + oldValue + "," + state); 443 } 444 resourceStates.put(res, state); 445 } 446 447 private int getXAState(XAResource res) { 448 Integer result = (Integer ) resourceStates.get(res); 449 if (result == null) return NOT_EXIST; 450 return result.intValue(); 451 } 452 453 457 public Enumeration listXAResources() { 458 return Collections.enumeration(resourceList.keySet()); 459 } 461 462 466 public boolean containsXAResource(XAResource res) { 467 return resourceList.containsKey(res); 468 } 469 470 static private void assert_prejdk14(boolean value) { 471 if (!value) { 472 Exception e = new Exception (); 473 _logger.log(Level.WARNING,"jts.assert",e); 474 } 475 } 476 477 private static byte[] parseSize(int size) { 478 479 switch(size) { 480 case 0: 481 return new byte[]{0}; 482 case 1: 483 return new byte[]{1}; 484 case 2: 485 return new byte[]{2}; 486 case 3: 487 return new byte[]{3}; 488 case 4: 489 return new byte[]{4}; 490 case 5: 491 return new byte[]{5}; 492 case 6: 493 return new byte[]{6}; 494 case 7: 495 return new byte[]{7}; 496 case 8: 497 return new byte[]{8}; 498 case 9: 499 return new byte[]{9}; 500 } 501 int j = 9; 502 byte [] res = new byte[10]; 503 while (size > 0) { 504 res[j--] = (byte) (size % 10); 505 size = size / 10; 506 } 507 int len = 9-j; 508 byte [] result = new byte[len]; 509 System.arraycopy(res, j+1, result, 0, len); 510 return result; 511 } 512 513 } 514 | Popular Tags |