1 29 30 package com.caucho.transaction; 31 32 import com.caucho.jca.UserTransactionImpl; 33 import com.caucho.jca.UserTransactionSuspendState; 34 import com.caucho.log.Log; 35 import com.caucho.transaction.xalog.AbstractXALogStream; 36 import com.caucho.util.Alarm; 37 import com.caucho.util.AlarmListener; 38 import com.caucho.util.CharBuffer; 39 import com.caucho.util.L10N; 40 41 import javax.transaction.*; 42 import javax.transaction.xa.XAException ; 43 import javax.transaction.xa.XAResource ; 44 import javax.transaction.xa.Xid ; 45 import java.util.ArrayList ; 46 import java.util.HashMap ; 47 import java.util.logging.Level ; 48 import java.util.logging.Logger ; 49 50 54 public class TransactionImpl implements Transaction, AlarmListener { 55 private static final Logger log = Log.open(TransactionImpl.class); 56 private static final L10N L = new L10N(TransactionImpl.class); 57 58 private final static long DEFAULT_TIMEOUT = 60000; 59 private final static long EXTRA_TIMEOUT = 60000; 60 private final static long MAX_TIMEOUT = 24 * 3600 * 1000L; 61 62 private final static int RES_ACTIVE = 0x1; 64 private final static int RES_SHARED_RM = 0x2; 66 private final static int RES_SUSPENDED = 0x4; 68 private final static int RES_COMMIT = 0x8; 70 71 private TransactionManagerImpl _manager; 72 73 private int _status; 75 76 private XidImpl _xid; 78 79 private boolean _isSuspended; 81 private boolean _isDead; 82 83 private int _resourceCount; 85 private XAResource []_resources; 87 private XidImpl []_resourceXid; 89 private int []_resourceState; 91 92 private UserTransactionImpl _userTransaction; 93 private UserTransactionSuspendState _suspendState; 94 95 private HashMap <String ,Object > _props; 96 97 private ArrayList <Synchronization> _syncList; 98 99 private Throwable _rollbackException; 100 101 private AbstractXALogStream _xaLog; 102 103 private long _timeout = 0; 104 private Alarm _alarm; 105 106 111 TransactionImpl(TransactionManagerImpl manager) 112 { 113 _manager = manager; 114 _timeout = _manager.getTimeout(); 115 _status = Status.STATUS_NO_TRANSACTION; 116 _alarm = new Alarm("xa-timeout", this, ClassLoader.getSystemClassLoader()); 117 } 118 119 122 public void setUserTransaction(UserTransactionImpl ut) 123 { 124 _userTransaction = ut; 125 } 126 127 130 boolean hasResources() 131 { 132 return _resourceCount > 0; 133 } 134 135 138 boolean isSuspended() 139 { 140 return _isSuspended; 141 } 142 143 146 boolean isDead() 147 { 148 return _isDead; 149 } 150 151 154 public boolean isEmpty() 155 { 156 if (_isDead) 157 return true; 158 else if (_resourceCount > 0) 159 return false; 160 else if (_syncList != null && _syncList.size() > 1) 162 return false; 163 else 164 return true; 165 } 166 167 170 void begin() 171 throws SystemException 172 { 173 if (_status != Status.STATUS_NO_TRANSACTION) { 174 try { 175 rollback(); 176 } catch (Throwable e) { 177 log.log(Level.WARNING, e.toString(), e); 178 } 179 180 throw new UnsupportedOperationException (L.l("Nested transactions are not supported. The previous transaction for this thread did not commit() or rollback(). Check that every UserTransaction.begin() has its commit() or rollback() in a finally block.")); 181 } 182 183 if (_isDead) 184 throw new IllegalStateException (L.l("Error trying to use dead transaction.")); 185 186 _status = Status.STATUS_ACTIVE; 187 188 _rollbackException = null; 189 190 if (_xid == null) 191 _xid = _manager.createXID(); 192 193 if (log.isLoggable(Level.FINE)) 194 log.fine("begin Transaction" + _xid); 195 196 if (_timeout > 0) { 197 _alarm.queue(_timeout + EXTRA_TIMEOUT); 198 } 199 } 200 201 207 public boolean enlistResource(XAResource resource) 208 throws RollbackException, SystemException 209 { 210 if (resource == null) 211 throw new IllegalArgumentException (L.l("Resource must not be null in enlistResource")); 212 213 if (_isSuspended) 214 throw new IllegalStateException (L.l("can't enlist with suspended transaction")); 215 if (_status == Status.STATUS_ACTIVE) { 216 } 218 else { 219 if (_status != Status.STATUS_MARKED_ROLLBACK) { 221 } 222 else if (_rollbackException != null) 223 throw RollbackExceptionWrapper.create(_rollbackException); 224 else 225 throw new RollbackException(L.l("can't enlist with rollback-only transaction")); 226 227 if (_status == Status.STATUS_NO_TRANSACTION) 228 throw new IllegalStateException (L.l("can't enlist with inactive transaction")); 229 230 throw new IllegalStateException (L.l("can't enlist with transaction in '{0}' state", 231 xaState(_status))); 232 } 233 234 if (_resources == null) { 236 _resources = new XAResource [16]; 237 _resourceState = new int[16]; 238 _resourceXid = new XidImpl[16]; 239 } 240 else if (_resources.length <= _resourceCount) { 241 int oldLength = _resources.length; 242 int newLength = 2 * oldLength; 243 244 XAResource []resources = new XAResource [newLength]; 245 int []resourceState = new int[newLength]; 246 XidImpl []resourceXid = new XidImpl[newLength]; 247 248 System.arraycopy(_resources, 0, resources, 0, oldLength); 249 System.arraycopy(_resourceState, 0, resourceState, 0, oldLength); 250 System.arraycopy(_resourceXid, 0, resourceXid, 0, oldLength); 251 252 _resources = resources; 253 _resourceState = resourceState; 254 _resourceXid = resourceXid; 255 } 256 257 int flags = XAResource.TMNOFLAGS; 258 259 XidImpl xid = _xid; 265 boolean hasNewResource = true; 266 267 for (int i = 0; i < _resourceCount; i++) { 268 if (_resources[i] != resource) { 269 } 270 else if ((_resourceState[i] & RES_ACTIVE) != 0) { 271 IllegalStateException exn; 272 exn = new IllegalStateException (L.l("Can't enlist same resource twice. Delist is required before calling enlist with an old resource.")); 273 274 setRollbackOnly(exn); 275 throw exn; 276 } 277 278 try { 279 if (_resources[i].isSameRM(resource)) { 280 flags = XAResource.TMJOIN; 281 xid = _resourceXid[i]; 282 283 if ((_resourceState[i] & RES_ACTIVE) == 0) { 284 _resources[i] = resource; 285 _resourceState[i] |= RES_ACTIVE; 286 hasNewResource = false; 287 } 288 289 break; 290 } 291 } catch (Exception e) { 292 log.log(Level.FINE, e.toString(), e); 293 } 294 } 295 296 if (_resourceCount > 0 && flags != XAResource.TMJOIN) 297 xid = new XidImpl(_xid, _resourceCount + 1); 298 299 try { 300 if (_timeout > 0) 301 resource.setTransactionTimeout((int) (_timeout / 1000L)); 302 303 if (log.isLoggable(Level.FINER)) { 304 if (flags == XAResource.TMJOIN) 305 log.finer("join-XA " + xid + " " + resource); 306 else 307 log.finer("start-XA " + xid + " " + resource); 308 } 309 310 resource.start(xid, flags); 311 } catch (XAException e) { 312 setRollbackOnly(e); 313 throw new SystemException(e); 314 } 315 316 if (hasNewResource) { 317 _resources[_resourceCount] = resource; 318 _resourceState[_resourceCount] = RES_ACTIVE; 319 320 if (flags == XAResource.TMJOIN) 321 _resourceState[_resourceCount] |= RES_SHARED_RM; 322 323 _resourceXid[_resourceCount] = xid; 324 _resourceCount++; 325 } 326 327 return true; 328 } 329 330 333 public boolean allowLocalTransactionOptimization() 334 { 335 return _resourceCount == 0; 337 } 338 339 342 public int getEnlistedResourceCount() 343 { 344 return _resourceCount; 345 } 346 347 355 public boolean delistResource(XAResource resource, int flag) 356 throws SystemException 357 { 358 if (_isSuspended) 359 throw new IllegalStateException (L.l("transaction is suspended")); 360 361 if (_resourceCount == 0) 362 return true; 363 364 int index; 365 366 for (index = _resourceCount - 1; index >= 0; index--) { 367 if (_resources[index].equals(resource)) 368 break; 369 } 370 371 if (index < 0) 372 return false; 373 374 if (_status == Status.STATUS_NO_TRANSACTION) { 377 for (; index + 1 < _resourceCount; index++) { 378 _resources[index] = _resources[index + 1]; 379 _resourceState[index] = _resourceState[index + 1]; 380 _resourceXid[index] = _resourceXid[index + 1]; 381 } 382 383 _resourceCount--; 384 385 return true; 386 } 387 388 if (_status == Status.STATUS_MARKED_ROLLBACK) 389 flag = XAResource.TMFAIL; 390 391 _resourceState[index] &= ~RES_ACTIVE; 392 393 try { 394 resource.end(_resourceXid[index], flag); 395 } catch (XAException e) { 396 setRollbackOnly(e); 397 throw new SystemException(e); 398 } 399 400 return true; 401 } 402 403 406 public void setAttribute(String var, Object value) 407 { 408 if (_props == null) 409 _props = new HashMap <String ,Object >(); 410 411 _props.put(var, value); 412 } 413 414 417 public Object getAttribute(String var) 418 { 419 if (_props != null) 420 return _props.get(var); 421 else 422 return null; 423 } 424 425 public Xid getXid() 426 { 427 return _xid; 428 } 429 430 433 public int getStatus() 434 { 435 return _status; 436 } 437 438 441 void suspend() 442 throws SystemException 443 { 444 if (_isSuspended) 445 throw new IllegalStateException (L.l("can't suspend already-suspended transaction")); 446 447 449 _isSuspended = true; 450 451 for (int i = _resourceCount - 1; i >= 0; i--) { 452 if ((_resourceState[i] & (RES_ACTIVE|RES_SUSPENDED)) == RES_ACTIVE) { 453 try { 454 XAResource resource = _resources[i]; 455 456 resource.end(_resourceXid[i], XAResource.TMSUSPEND); 457 } catch (Exception e) { 458 setRollbackOnly(e); 459 } 460 } 461 } 462 463 if (_userTransaction != null) 464 _suspendState = _userTransaction.suspend(); 465 466 if (log.isLoggable(Level.FINER)) 467 log.fine(_xid + " suspended"); 468 } 469 470 473 void resume() 474 throws SystemException 475 { 476 if (! _isSuspended) 477 throw new IllegalStateException (L.l("can't resume non-suspended transaction")); 478 479 _alarm.queue(_timeout + EXTRA_TIMEOUT); 480 481 for (int i = _resourceCount - 1; i >= 0; i--) { 482 if ((_resourceState[i] & (RES_ACTIVE|RES_SUSPENDED)) == RES_ACTIVE) { 483 try { 484 XAResource resource = _resources[i]; 485 486 resource.start(_resourceXid[i], XAResource.TMRESUME); 487 } catch (Exception e) { 488 setRollbackOnly(e); 489 } 490 } 491 } 492 493 if (_userTransaction != null) 494 _userTransaction.resume(_suspendState); 495 496 _isSuspended = false; 497 498 if (log.isLoggable(Level.FINE)) 499 log.fine(_xid + " resume"); 500 } 501 502 505 public void registerSynchronization(Synchronization sync) 506 { 507 if (_syncList == null) 508 _syncList = new ArrayList <Synchronization>(); 509 510 _syncList.add(sync); 511 } 512 513 516 public void setRollbackOnly() 517 throws SystemException 518 { 519 if (_status != Status.STATUS_ACTIVE && 520 _status != Status.STATUS_MARKED_ROLLBACK) 521 throw new IllegalStateException (L.l("can't set rollback-only")); 522 523 _status = Status.STATUS_MARKED_ROLLBACK; 524 525 _timeout = 0; 526 527 if (log.isLoggable(Level.FINER)) 528 log.finer("setting rollback-only"); 529 } 530 531 534 public void setRollbackOnly(Throwable exn) 535 { 536 if (_status != Status.STATUS_ACTIVE && 537 _status != Status.STATUS_MARKED_ROLLBACK) 538 throw new IllegalStateException (L.l("can't set rollback-only")); 539 540 _status = Status.STATUS_MARKED_ROLLBACK; 541 542 if (_rollbackException == null) 543 _rollbackException = exn; 544 545 if (log.isLoggable(Level.FINER)) 546 log.log(Level.FINER, "setting rollback-only: " + exn.toString(), exn); 547 } 548 549 552 public void commit() 553 throws RollbackException, HeuristicMixedException, 554 HeuristicRollbackException, SystemException 555 { 556 _alarm.dequeue(); 557 558 Exception heuristicExn = null; 559 560 try { 561 callBeforeCompletion(); 562 } catch (Throwable e) { 563 setRollbackOnly(e); 564 } 565 566 try { 567 if (_status != Status.STATUS_ACTIVE) { 568 switch (_status) { 569 case Status.STATUS_MARKED_ROLLBACK: 570 rollbackInt(); 571 if (_rollbackException != null) 572 throw new RollbackExceptionWrapper(_rollbackException); 573 else 574 throw new RollbackException(L.l("Transaction has been marked rolled back.")); 575 576 case Status.STATUS_NO_TRANSACTION: 577 throw new IllegalStateException (L.l("Can't commit outside of a transaction. Either the UserTransaction.begin() is missing or the transaction has already been committed or rolled back.")); 578 579 default: 580 rollbackInt(); 581 throw new IllegalStateException (L.l("can't commit {0}", String.valueOf(_status))); 582 } 583 } 584 585 if (log.isLoggable(Level.FINE)) 586 log.fine("committing Transaction" + _xid); 587 588 if (_resourceCount > 0) { 589 _status = Status.STATUS_PREPARING; 590 591 AbstractXALogStream xaLog = _manager.getXALogStream(); 592 boolean hasPrepare = false; 593 boolean allowSinglePhase = false; 594 595 for (int i = _resourceCount - 1; i >= 0; i--) { 596 XAResource resource = (XAResource ) _resources[i]; 597 598 if (i == 0 && (xaLog == null || ! hasPrepare)) { 599 _resourceState[0] |= RES_COMMIT; 601 602 allowSinglePhase = true; 603 break; 604 } 605 606 if ((_resourceState[i] & RES_SHARED_RM) == 0) { 607 try { 608 int prepare = resource.prepare(_resourceXid[i]); 609 610 if (prepare == XAResource.XA_RDONLY) { 611 } 612 else if (prepare == XAResource.XA_OK) { 613 hasPrepare = true; 614 _resourceState[i] |= RES_COMMIT; 615 } 616 else { 617 log.finer("unexpected prepare result " + prepare); 618 rollbackInt(); 619 } 620 } catch (XAException e) { 621 heuristicExn = heuristicException(heuristicExn, e); 622 rollbackInt(); 623 throw new RollbackExceptionWrapper(L.l("all commits rolled back"), 624 heuristicExn); 625 } 626 } 627 } 628 629 if (hasPrepare && xaLog != null) { 630 _xaLog = xaLog; 631 632 xaLog.writeTMCommit(_xid); 633 } 634 635 _status = Status.STATUS_COMMITTING; 636 637 if (allowSinglePhase) { 638 try { 639 XAResource resource = (XAResource ) _resources[0]; 640 641 if ((_resourceState[0] & RES_COMMIT) != 0) 642 resource.commit(_xid, true); 643 644 if (_timeout > 0) 645 resource.setTransactionTimeout(0); 646 } catch (XAException e) { 647 log.log(Level.FINE, e.toString(), e); 648 649 heuristicExn = heuristicException(heuristicExn, e); 650 } 651 } 652 653 for (int i = 0; i < _resourceCount; i++) { 654 XAResource resource = (XAResource ) _resources[i]; 655 656 if (i == 0 && allowSinglePhase) 657 continue; 658 659 if ((_resourceState[i] & RES_SHARED_RM) != 0) 660 continue; 661 if ((_resourceState[i] & RES_COMMIT) == 0) 662 continue; 663 664 if (heuristicExn == null) { 665 try { 666 resource.commit(_resourceXid[i], false); 667 668 if (_timeout > 0) 669 resource.setTransactionTimeout(0); 670 } catch (XAException e) { 671 heuristicExn = e; 672 log.log(Level.FINE, e.toString(), e); 673 } 674 } 675 else { 676 try { 677 resource.rollback(_resourceXid[i]); 678 679 if (_timeout > 0) 680 resource.setTransactionTimeout(0); 681 } catch (XAException e) { 682 log.log(Level.FINE, e.toString(), e); 683 } 684 } 685 } 686 } 687 688 if (heuristicExn != null && log.isLoggable(Level.FINE)) 689 log.fine("failed Transaction[" + _xid + "]: " + heuristicExn); 690 691 if (heuristicExn == null) 692 _status = Status.STATUS_COMMITTED; 693 else if (heuristicExn instanceof RollbackException) { 694 _status = Status.STATUS_ROLLEDBACK; 695 throw (RollbackException) heuristicExn; 696 } 697 else if (heuristicExn instanceof HeuristicMixedException) { 698 _status = Status.STATUS_ROLLEDBACK; 699 throw (HeuristicMixedException) heuristicExn; 700 } 701 else if (heuristicExn instanceof HeuristicRollbackException) { 702 _status = Status.STATUS_ROLLEDBACK; 703 throw (HeuristicRollbackException) heuristicExn; 704 } 705 else if (heuristicExn instanceof SystemException) { 706 _status = Status.STATUS_ROLLEDBACK; 707 throw (SystemException) heuristicExn; 708 } 709 else { 710 _status = Status.STATUS_ROLLEDBACK; 711 throw RollbackExceptionWrapper.create(heuristicExn); 712 } 713 } finally { 714 callAfterCompletion(); 715 } 716 } 717 718 721 public void rollback() 722 { 723 _alarm.dequeue(); 724 725 try { 726 callBeforeCompletion(); 727 } catch (Throwable e) { 728 setRollbackOnly(e); 729 } 730 731 try { 732 switch (_status) { 733 case Status.STATUS_ACTIVE: 734 case Status.STATUS_MARKED_ROLLBACK: 735 break; 737 738 case Status.STATUS_NO_TRANSACTION: 739 throw new IllegalStateException (L.l("Can't rollback outside of a transaction. Either the UserTransaction.begin() is missing or the transaction has already been committed or rolled back.")); 740 741 default: 742 rollbackInt(); 743 throw new IllegalStateException (L.l("Can't rollback in state: {0}", String.valueOf(_status))); 744 } 745 746 _status = Status.STATUS_MARKED_ROLLBACK; 747 748 rollbackInt(); 749 } finally { 750 callAfterCompletion(); 751 } 752 } 753 754 758 private Exception heuristicException(Exception oldException, 759 XAException xaException) 760 { 761 switch (xaException.errorCode) { 762 case XAException.XA_HEURHAZ: 763 case XAException.XA_HEURCOM: 764 return oldException; 765 766 case XAException.XA_HEURRB: 767 if (oldException instanceof HeuristicMixedException) 768 return oldException; 769 else if (oldException instanceof HeuristicRollbackException) 770 return oldException; 771 else if (oldException instanceof RollbackException) 772 return oldException; 773 else 774 return new HeuristicRollbackException(getXAMessage(xaException)); 775 776 default: 777 if (oldException instanceof SystemException) 778 return oldException; 779 else 780 return new SystemExceptionWrapper(getXAMessage(xaException), 781 xaException); 782 } 783 } 784 785 788 private void rollbackInt() 789 { 790 _status = Status.STATUS_ROLLING_BACK; 791 792 if (log.isLoggable(Level.FINE)) 793 log.fine("rollback Transaction[" + _xid + "]"); 794 795 for (int i = 0; i < _resourceCount; i++) { 796 XAResource resource = (XAResource ) _resources[i]; 797 798 if ((_resourceState[i] & RES_SHARED_RM) != 0) 799 continue; 800 801 try { 802 resource.rollback(_resourceXid[i]); 803 804 if (_timeout > 0) 805 resource.setTransactionTimeout(0); 806 } catch (Throwable e) { 807 log.log(Level.FINE, e.toString(), e); 808 } 809 } 810 811 _status = Status.STATUS_ROLLEDBACK; 812 } 813 814 818 private void callBeforeCompletion() 819 { 820 int length = _syncList == null ? 0 : _syncList.size(); 821 822 for (int i = 0; i < length; i++) { 823 Synchronization sync = _syncList.get(i); 824 825 try { 826 sync.beforeCompletion(); 827 } catch (Throwable e) { 828 log.log(Level.FINE, e.toString(), e); 829 } 830 } 831 832 for (int i = _resourceCount - 1; i >= 0; i--) { 834 XAResource resource = _resources[i]; 835 836 int flag; 837 838 if (_status == Status.STATUS_MARKED_ROLLBACK) 839 flag = XAResource.TMFAIL; 840 else 841 flag = XAResource.TMSUCCESS; 842 843 try { 844 if ((_resourceState[i] & RES_ACTIVE) != 0) 845 resource.end(_resourceXid[i], flag); 846 } catch (Throwable e) { 847 log.log(Level.FINE, e.toString(), e); 848 setRollbackOnly(e); 849 } 850 } 851 } 852 853 857 private void callAfterCompletion() 858 { 859 ArrayList <Synchronization> syncList = _syncList; 860 _syncList = null; 861 862 _userTransaction = null; 863 864 XidImpl xid = _xid; 865 _xid = null; 866 867 int status = _status; 868 _status = Status.STATUS_NO_TRANSACTION; 869 870 _rollbackException = null; 871 872 for (int i = _resourceCount - 1; i >= 0; i--) 874 _resources[i] = null; 875 876 _resourceCount = 0; 877 878 AbstractXALogStream xaLog = _xaLog; 879 _xaLog = null; 880 881 if (xaLog != null) { 882 try { 883 xaLog.writeTMFinish(xid); 884 } catch (Throwable e) { 885 log.log(Level.FINER, e.toString(), e); 886 } 887 } 888 889 int length = syncList == null ? 0 : syncList.size(); 890 for (int i = 0; i < length; i++) { 891 Synchronization sync = (Synchronization) syncList.get(i); 892 893 try { 894 sync.afterCompletion(status); 895 } catch (Throwable e) { 896 log.log(Level.FINE, e.toString(), e); 897 } 898 } 899 900 if (_props != null) 901 _props.clear(); 902 } 903 904 907 public void setTransactionTimeout(int seconds) 908 throws SystemException 909 { 910 if (seconds == 0) 911 _timeout = _manager.getTimeout(); 912 else if (seconds < 0) 913 _timeout = MAX_TIMEOUT; 914 else { 915 _timeout = 1000L * (long) seconds; 916 } 917 } 918 919 922 public int getTransactionTimeout() 923 throws SystemException 924 { 925 if (_timeout < 0) 926 return -1; 927 else 928 return (int) (_timeout / 1000L); 929 } 930 931 public void handleAlarm(Alarm alarm) 932 { 933 try { 934 log.warning(L.l("{0}: timed out after {1} seconds.", 935 this, 936 String.valueOf(getTransactionTimeout()))); 937 938 setRollbackOnly(); 939 940 } catch (Throwable e) { 945 log.log(Level.FINE, e.toString(), e); 946 } 947 } 948 949 953 public void close() 954 { 955 _isDead = true; 956 _alarm.dequeue(); 957 958 try { 959 if (_status != Status.STATUS_NO_TRANSACTION) 960 rollback(); 961 } catch (Throwable e) { 962 log.log(Level.FINE, e.toString(), e); 963 } 964 965 if (_syncList != null) 966 _syncList.clear(); 967 968 for (int i = _resourceCount - 1; i >= 0; i--) 969 _resources[i] = null; 970 971 _resourceCount = 0; 972 973 _xid = null; 974 } 975 976 979 public String toString() 980 { 981 if (_xid == null) 982 return "Transaction[]"; 983 984 CharBuffer cb = new CharBuffer(); 985 986 cb.append("Transaction["); 987 988 byte []branch = _xid.getBranchQualifier(); 989 990 addByte(cb, branch[0]); 991 992 cb.append(":"); 993 994 byte []global = _xid.getGlobalTransactionId(); 995 for (int i = 24; i < 28; i++) 996 addByte(cb, global[i]); 997 998 cb.append("]"); 999 1000 return cb.toString(); 1001 } 1002 1003 1006 private void addByte(CharBuffer cb, int b) 1007 { 1008 int h = (b / 16) & 0xf; 1009 int l = b & 0xf; 1010 1011 if (h >= 10) 1012 cb.append((char) ('a' + h - 10)); 1013 else 1014 cb.append((char) ('0' + h)); 1015 1016 if (l >= 10) 1017 cb.append((char) ('a' + l - 10)); 1018 else 1019 cb.append((char) ('0' + l)); 1020 } 1021 1022 1025 private static String getXAMessage(XAException xaException) 1026 { 1027 if (xaException.getMessage() != null && 1028 ! xaException.getMessage().equals("")) 1029 return xaException.getMessage(); 1030 else 1031 return (xaName(xaException.errorCode) + ": " + 1032 xaMessage(xaException.errorCode)); 1033 } 1034 1035 1038 private static String xaState(int xaState) 1039 { 1040 switch (xaState) { 1041 case Status.STATUS_ACTIVE: 1042 return "ACTIVE"; 1043 case Status.STATUS_MARKED_ROLLBACK: 1044 return "MARKED-ROLLBACK"; 1045 case Status.STATUS_PREPARED: 1046 return "PREPARED"; 1047 case Status.STATUS_COMMITTED: 1048 return "COMITTED"; 1049 case Status.STATUS_ROLLEDBACK: 1050 return "ROLLEDBACK"; 1051 case Status.STATUS_PREPARING: 1052 return "PREPARING"; 1053 case Status.STATUS_COMMITTING: 1054 return "COMMITTING"; 1055 case Status.STATUS_ROLLING_BACK: 1056 return "ROLLING_BACK"; 1057 default: 1058 return "XA-STATE(" + xaState + ")"; 1059 } 1060 } 1061 1062 1065 private static String xaName(int xaCode) 1066 { 1067 switch (xaCode) { 1068 case XAException.XA_RBROLLBACK: 1070 return "XA_RBROLLBACK"; 1071 case XAException.XA_RBCOMMFAIL: 1072 return "XA_RBCOMMFAIL"; 1073 case XAException.XA_RBDEADLOCK: 1074 return "XA_RBDEADLOCK"; 1075 case XAException.XA_RBINTEGRITY: 1076 return "XA_RBINTEGRITY"; 1077 case XAException.XA_RBOTHER: 1078 return "XA_RBOTHER"; 1079 case XAException.XA_RBPROTO: 1080 return "XA_RBPROTO"; 1081 case XAException.XA_RBTIMEOUT: 1082 return "XA_RBTIMEOUT"; 1083 case XAException.XA_RBTRANSIENT: 1084 return "XA_RBTRANSIENT"; 1085 1086 case XAException.XA_NOMIGRATE: 1088 return "XA_NOMIGRATE"; 1089 1090 case XAException.XA_HEURHAZ: 1092 return "XA_HEURHAZ"; 1093 case XAException.XA_HEURCOM: 1094 return "XA_HEURCOM"; 1095 case XAException.XA_HEURRB: 1096 return "XA_HEURRB"; 1097 case XAException.XA_HEURMIX: 1098 return "XA_HEURMIX"; 1099 case XAException.XA_RDONLY: 1100 return "XA_RDONLY"; 1101 1102 case XAException.XAER_RMERR: 1104 return "XA_RMERR"; 1105 case XAException.XAER_NOTA: 1106 return "XA_NOTA"; 1107 case XAException.XAER_INVAL: 1108 return "XA_INVAL"; 1109 case XAException.XAER_PROTO: 1110 return "XA_PROTO"; 1111 case XAException.XAER_RMFAIL: 1112 return "XA_RMFAIL"; 1113 case XAException.XAER_DUPID: 1114 return "XA_DUPID"; 1115 case XAException.XAER_OUTSIDE: 1116 return "XA_OUTSIDE"; 1117 1118 default: 1119 return "XA(" + xaCode + ")"; 1120 } 1121 } 1122 1123 1126 private static String xaMessage(int xaCode) 1127 { 1128 switch (xaCode) { 1129 case XAException.XA_RBROLLBACK: 1131 case XAException.XA_RBOTHER: 1132 return L.l("Resource rolled back for an unspecified reason."); 1133 case XAException.XA_RBCOMMFAIL: 1134 return L.l("Resource rolled back because of a communication failure."); 1135 case XAException.XA_RBDEADLOCK: 1136 return L.l("Resource rolled back because of a deadlock."); 1137 case XAException.XA_RBINTEGRITY: 1138 return L.l("Resource rolled back because of an integrity check failure."); 1139 case XAException.XA_RBPROTO: 1140 return L.l("Resource rolled back because of a protocol error in the resource manager."); 1141 case XAException.XA_RBTIMEOUT: 1142 return L.l("Resource rolled back because of a timeout."); 1143 case XAException.XA_RBTRANSIENT: 1144 return L.l("Resource rolled back because of transient error."); 1145 1146 case XAException.XA_NOMIGRATE: 1148 return L.l("Resumption must occur where the suspension occurred."); 1149 1150 case XAException.XA_HEURHAZ: 1152 return L.l("Resource may have been heuristically completed."); 1153 case XAException.XA_HEURCOM: 1154 return L.l("Resource has been heuristically committed."); 1155 case XAException.XA_HEURRB: 1156 return L.l("Resource has been heuristically rolled back."); 1157 case XAException.XA_HEURMIX: 1158 return L.l("Resource has been heuristically committed and rolled back."); 1159 case XAException.XA_RDONLY: 1160 return L.l("Resource was read-only and has been heuristically committed."); 1161 1162 case XAException.XAER_RMERR: 1164 return L.l("Resource manager error."); 1165 case XAException.XAER_NOTA: 1166 return L.l("The XID (transaction identifier) was invalid."); 1167 case XAException.XAER_INVAL: 1168 return L.l("Invalid arguments were given."); 1169 case XAException.XAER_PROTO: 1170 return L.l("Method called in an invalid context."); 1171 case XAException.XAER_RMFAIL: 1172 return L.l("Resource manager is unavailable."); 1173 case XAException.XAER_DUPID: 1174 return L.l("Duplicate XID (transaction identifier)."); 1175 case XAException.XAER_OUTSIDE: 1176 return L.l("Resource manager called outside of transaction."); 1177 1178 default: 1179 return ""; 1180 } 1181 } 1182} 1183 | Popular Tags |