1 22 package org.jboss.tm; 23 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.Collections ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 32 import javax.resource.spi.work.Work ; 33 import javax.resource.spi.work.WorkCompletedException ; 34 import javax.resource.spi.work.WorkException ; 35 import javax.transaction.HeuristicMixedException ; 36 import javax.transaction.HeuristicRollbackException ; 37 import javax.transaction.InvalidTransactionException ; 38 import javax.transaction.NotSupportedException ; 39 import javax.transaction.RollbackException ; 40 import javax.transaction.Status ; 41 import javax.transaction.SystemException ; 42 import javax.transaction.Transaction ; 43 import javax.transaction.TransactionManager ; 44 import javax.transaction.xa.XAException ; 45 import javax.transaction.xa.Xid ; 46 47 import org.jboss.logging.Logger; 48 import org.jboss.tm.integrity.TransactionIntegrity; 49 import org.jboss.tm.recovery.LogRecord; 50 import org.jboss.tm.recovery.RecoveryLogger; 51 import org.jboss.tm.recovery.TxCompletionHandler; 52 import org.jboss.tm.remoting.interfaces.Coordinator; 53 import org.jboss.tm.remoting.interfaces.RecoveryCoordinator; 54 import org.jboss.tm.remoting.interfaces.Resource; 55 import org.jboss.tm.remoting.interfaces.TxPropagationContext; 56 import org.jboss.util.UnexpectedThrowable; 57 import org.jboss.util.UnreachableStatementException; 58 59 72 public class TxManager 73 implements TransactionManager , 74 TransactionPropagationContextImporter, 75 TransactionPropagationContextFactory, 76 TransactionLocalDelegate, 77 TransactionTimeoutConfiguration, 78 JBossXATerminator, 79 StringRemoteRefConverter 80 { 81 83 85 88 private boolean globalIdsEnabled = false; 89 90 93 private boolean dtmEnabled = false; 94 95 98 private boolean interruptThreads = false; 99 100 103 private Logger log = Logger.getLogger(this.getClass()); 104 105 108 private boolean trace = log.isTraceEnabled(); 109 110 114 private long timeOut = 5 * 60 * 1000; 115 116 126 private volatile int commitCount; 127 130 private volatile int rollbackCount; 131 132 133 private RecoveryLogger recoveryLogger; 134 135 136 private boolean recoveryPending = true; 137 138 139 private TransactionIntegrity integrity; 140 141 142 private int completionRetryLimit = 0; 144 145 private int completionRetryTimeout = 1 * 1000; 147 148 private int xaRetryTimeout = 60 * 1000; 149 150 151 private int preparedTimeout = 60 * 1000; 152 153 154 private boolean rootBranchRemembersHeuristicDecisions = true; 155 156 157 private boolean reportHeuristicHazardAsHeuristicMixed = false; 158 159 161 164 private static TxManager singleton = new TxManager(); 165 166 169 public static TxManager getInstance() 170 { 171 return singleton; 172 } 173 174 176 180 private TxManager() 181 { 182 TransactionImpl.defaultXidFactory(); 184 } 185 186 188 193 public void clear() 194 { 195 Collection txCollection = localIdTx.values(); 196 synchronized (localIdTx) 197 { 198 Iterator i = txCollection.iterator(); 199 while (i.hasNext()) 200 { 201 TransactionImpl tx = (TransactionImpl) i.next(); 202 tx.deactivate(); 203 } 204 } 205 localIdTx.clear(); 206 if (globalIdsEnabled) 207 globalIdTx.clear(); 208 } 209 210 213 public void setGlobalIdsEnabled(boolean newValue) 214 { 215 trace = log.isTraceEnabled(); XidImpl.setTrulyGlobalIdsEnabled(newValue); 217 globalIdsEnabled = newValue; 218 } 219 220 223 public boolean getGlobalIdsEnabled() 224 { 225 return globalIdsEnabled; 226 } 227 228 233 public void setInterruptThreads(boolean interruptThreads) 234 { 235 this.interruptThreads = interruptThreads; 236 } 237 238 243 public boolean isInterruptThreads() 244 { 245 return interruptThreads; 246 } 247 248 253 public void setRecoveryLogger(RecoveryLogger recoveryLogger) 254 { 255 this.recoveryLogger = recoveryLogger; 256 } 257 258 263 public RecoveryLogger getRecoveryLogger() 264 { 265 return recoveryLogger; 266 } 267 268 272 public void clearRecoveryPending() 273 { 274 this.recoveryPending = false; 275 } 276 277 282 public boolean isRecoveryPending() 283 { 284 return recoveryPending; 285 } 286 287 292 public void setTransactionIntegrity(TransactionIntegrity integrity) 293 { 294 this.integrity = integrity; 295 } 296 297 302 public TransactionIntegrity getTransactionIntegrity() 303 { 304 return integrity; 305 } 306 307 318 public void setCompletionRetryLimit(int maxCompletionRetries) 319 { 320 this.completionRetryLimit = maxCompletionRetries; 321 } 322 323 334 public int getCompletionRetryLimit() 335 { 336 return completionRetryLimit; 337 } 338 339 355 public void setCompletionRetryTimeout(int seconds) 356 { 357 this.completionRetryTimeout = 1000 * seconds; 358 } 359 360 376 public int getCompletionRetryTimeout() 377 { 378 return completionRetryTimeout / 1000; 379 } 380 381 388 public int getCompletionRetryTimeoutMillis() 389 { 390 return xaRetryTimeout; 391 } 392 393 399 public void setXARetryTimeout(int seconds) 400 { 401 this.xaRetryTimeout = 1000 * seconds; 402 } 403 404 409 public int getXARetryTimeout() 410 { 411 return xaRetryTimeout / 1000; 412 } 413 414 420 public int getXARetryTimeoutMillis() 421 { 422 return xaRetryTimeout; 423 } 424 425 434 public void setPreparedTimeout(int seconds) 435 { 436 this.preparedTimeout = 1000 * seconds; 437 } 438 439 448 public int getPreparedTimeout() 449 { 450 return preparedTimeout / 1000; 451 } 452 453 459 public int getPreparedTimeoutMillis() 460 { 461 return preparedTimeout; 462 } 463 464 475 public void setRootBranchRemembersHeuristicDecisions(boolean newValue) 476 { 477 rootBranchRemembersHeuristicDecisions = newValue; 478 } 479 480 491 public boolean isRootBranchRemembersHeuristicDecisions() 492 { 493 return rootBranchRemembersHeuristicDecisions; 494 } 495 496 513 public void setReportHeuristicHazardAsHeuristicMixed(boolean newValue) 514 { 515 reportHeuristicHazardAsHeuristicMixed = newValue; 516 } 517 518 534 public boolean isReportHeuristicHazardAsHeuristicMixed() 535 { 536 return reportHeuristicHazardAsHeuristicMixed; 537 } 538 539 543 public void begin() 544 throws NotSupportedException , 545 SystemException 546 { 547 trace = log.isTraceEnabled(); 549 ThreadInfo ti = getThreadInfo(); 550 TransactionImpl current = ti.tx; 551 552 if (current != null) 553 { 554 if (current.isDone()) 555 disassociateThread(ti); 556 else 557 throw new NotSupportedException 558 ("Transaction already active, cannot nest transactions."); 559 } 560 561 long timeout = (ti.timeout == 0) ? timeOut : ti.timeout; 562 TransactionImpl tx = new TransactionImpl(timeout); 563 associateThread(ti, tx); 564 localIdTx.put(tx.getLocalId(), tx); 565 if (globalIdsEnabled) 566 globalIdTx.put(tx.getGlobalId(), tx); 567 568 if (trace) 569 log.trace("began tx: " + tx); 570 } 571 572 575 public void commit() 576 throws RollbackException , 577 HeuristicMixedException , 578 HeuristicRollbackException , 579 SecurityException , 580 IllegalStateException , 581 SystemException 582 { 583 ThreadInfo ti = getThreadInfo(); 584 TransactionImpl current = ti.tx; 585 586 if (current != null) 587 { 588 current.commit(); 589 disassociateThread(ti); 590 if (trace) 591 log.trace("commited tx: " + current); 592 } 593 else 594 throw new IllegalStateException ("No transaction."); 595 } 596 597 602 public int getStatus() 603 throws SystemException 604 { 605 ThreadInfo ti = getThreadInfo(); 606 TransactionImpl current = ti.tx; 607 608 if (current != null) 609 { 610 if (current.isDone()) 611 disassociateThread(ti); 612 else 613 return current.getStatus(); 614 } 615 return Status.STATUS_NO_TRANSACTION; 616 } 617 618 622 public Transaction getTransaction() 623 throws SystemException 624 { 625 ThreadInfo ti = getThreadInfo(); 626 TransactionImpl current = ti.tx; 627 628 if (current != null && current.isDone()) 629 { 630 current = null; 631 disassociateThread(ti); 632 } 633 634 return current; 635 } 636 637 644 public void resume(Transaction transaction) 645 throws InvalidTransactionException , 646 IllegalStateException , 647 SystemException 648 { 649 if (transaction != null && !(transaction instanceof TransactionImpl)) 650 throw new RuntimeException ("Not a TransactionImpl, but a " + 651 transaction.getClass().getName()); 652 653 ThreadInfo ti = getThreadInfo(); 654 TransactionImpl current = ti.tx; 655 656 if (current != null) 657 { 658 if (current.isDone()) 659 current = ti.tx = null; 660 else 661 throw new IllegalStateException ("Already associated with a tx"); 662 } 663 664 if (current != transaction) 665 { 666 associateThread(ti, (TransactionImpl) transaction); 667 } 668 669 if (trace) 670 log.trace("resumed tx: " + ti.tx); 671 } 672 673 681 public Transaction suspend() 682 throws SystemException 683 { 684 ThreadInfo ti = getThreadInfo(); 685 TransactionImpl current = ti.tx; 686 687 if (current != null) 688 { 689 current.disassociateCurrentThread(); 690 ti.tx = null; 691 692 if (trace) 693 log.trace("suspended tx: " + current); 694 695 if (current.isDone()) 696 current = null; 697 } 698 699 return current; 700 } 701 702 705 public void rollback() 706 throws IllegalStateException , 707 SecurityException , 708 SystemException 709 { 710 ThreadInfo ti = getThreadInfo(); 711 TransactionImpl current = ti.tx; 712 713 if (current != null) 714 { 715 if (!current.isDone()) 716 { 717 current.rollback(); 718 719 if (trace) 720 log.trace("rolled back tx: " + current); 721 return; 722 } 723 disassociateThread(ti); 724 } 725 throw new IllegalStateException ("No transaction."); 726 } 727 728 732 public void setRollbackOnly() 733 throws IllegalStateException , 734 SystemException 735 { 736 ThreadInfo ti = getThreadInfo(); 737 TransactionImpl current = ti.tx; 738 739 if (current != null) 740 { 741 if (!current.isDone()) 742 { 743 current.setRollbackOnly(); 744 745 if (trace) 746 log.trace("tx marked for rollback only: " + current); 747 return; 748 } 749 ti.tx = null; 750 } 751 throw new IllegalStateException ("No transaction."); 752 } 753 754 public int getTransactionTimeout() 755 { 756 return (int) (getThreadInfo().timeout / 1000); 757 } 758 759 763 public void setTransactionTimeout(int seconds) 764 throws SystemException 765 { 766 getThreadInfo().timeout = 1000 * seconds; 767 768 if (trace) 769 log.trace("tx timeout is now: " + seconds + "s"); 770 } 771 772 777 public void setDefaultTransactionTimeout(int seconds) 778 { 779 timeOut = 1000L * seconds; 780 781 if (trace) 782 log.trace("default tx timeout is now: " + seconds + "s"); 783 } 784 785 790 public int getDefaultTransactionTimeout() 791 { 792 return (int) (timeOut / 1000); 793 } 794 795 public long getTimeLeftBeforeTransactionTimeout(boolean errorRollback) throws RollbackException 796 { 797 try 798 { 799 ThreadInfo ti = getThreadInfo(); 800 TransactionImpl current = ti.tx; 801 if (current != null && current.isDone()) 802 { 803 disassociateThread(ti); 804 return -1; 805 } 806 return current.getTimeLeftBeforeTimeout(errorRollback); 807 } 808 catch (RollbackException e) 809 { 810 throw e; 811 } 812 catch (Exception ignored) 813 { 814 return -1; 815 } 816 } 817 818 822 public Transaction disassociateThread() 823 { 824 return disassociateThread(getThreadInfo()); 825 } 826 827 private Transaction disassociateThread(ThreadInfo ti) 828 { 829 TransactionImpl current = ti.tx; 830 ti.tx = null; 831 current.disassociateCurrentThread(); 832 return current; 833 } 834 835 public void associateThread(Transaction transaction) 836 { 837 if (transaction != null && !(transaction instanceof TransactionImpl)) 838 throw new RuntimeException ("Not a TransactionImpl, but a " + 839 transaction.getClass().getName()); 840 841 TransactionImpl transactionImpl = (TransactionImpl) transaction; 843 ThreadInfo ti = getThreadInfo(); 844 ti.tx = transactionImpl; 845 transactionImpl.associateCurrentThread(); 846 } 847 848 private void associateThread(ThreadInfo ti, TransactionImpl transaction) 849 { 850 ti.tx = transaction; 852 transaction.associateCurrentThread(); 853 } 854 855 858 public int getTransactionCount() 859 { 860 return localIdTx.size(); 861 } 862 863 866 public long getCommitCount() 867 { 868 return commitCount; 869 } 870 871 874 public long getRollbackCount() 875 { 876 return rollbackCount; 877 } 878 879 884 public String listInDoubtTransactions() 885 { 886 throw new org.jboss.util.NotImplementedException(); 888 } 889 890 896 public void heuristicallyCommit(long localTransactionId) 897 { 898 throw new org.jboss.util.NotImplementedException(); 900 } 901 902 905 public void heuristicallyCommitAll() 906 { 907 throw new org.jboss.util.NotImplementedException(); 909 } 910 911 917 public void heuristicallyRollback(long localTransactionId) 918 { 919 throw new org.jboss.util.NotImplementedException(); 921 } 922 923 926 public void heuristicallyRollbackAll() 927 { 928 throw new org.jboss.util.NotImplementedException(); 930 } 931 932 944 public String listHeuristicallyCompletedTransactions() 945 { 946 throw new org.jboss.util.NotImplementedException(); 948 } 949 950 958 public void forget(long localTransactionId) 959 { 960 throw new org.jboss.util.NotImplementedException(); 962 } 963 964 968 public void forgetAll() 969 { 970 throw new org.jboss.util.NotImplementedException(); 972 } 973 974 976 991 public Transaction importTransactionPropagationContext(Object tpc) 992 { 993 if (tpc instanceof LocalId) 994 { 995 LocalId id = (LocalId) tpc; 996 return (Transaction ) localIdTx.get(id); 997 } 998 else if (tpc instanceof GlobalId && globalIdsEnabled) 999 { 1000 GlobalId id = (GlobalId) tpc; 1001 Transaction tx = (Transaction ) globalIdTx.get(id); 1002 if (trace) 1003 { 1004 if (tx != null) 1005 log.trace("Successfully imported transaction context " + tpc); 1006 else 1007 log.trace("Could not import transaction context " + tpc); 1008 } 1009 return tx; 1010 } 1011 else if (tpc instanceof TxPropagationContext && dtmEnabled) 1012 { 1013 TxPropagationContext fullTpc = (TxPropagationContext) tpc; 1014 Transaction tx = importExternalTransaction(fullTpc.formatId, 1015 fullTpc.globalId, 1016 fullTpc.coordinator, 1017 fullTpc.timeout * 1000); 1018 if (trace) 1019 { 1020 if (tx != null) 1021 log.trace("Successfully imported transaction context " + tpc); 1022 else 1023 log.trace("Could not import transaction context " + tpc); 1024 } 1025 return tx; 1026 } 1027 log.warn("Cannot import transaction propagation context: " + tpc); 1028 return null; 1029 } 1030 1031 1033 1036 public Object getTransactionPropagationContext() 1037 { 1038 return getTransactionPropagationContext(getThreadInfo().tx); 1039 } 1040 1041 1044 public Object getTransactionPropagationContext(Transaction t) 1045 { 1046 if (t == null) 1048 return null; 1049 if (!(t instanceof TransactionImpl)) 1050 { 1051 log.warn("Cannot export transaction propagation context: " + t); 1052 return null; 1053 } 1054 1055 TransactionImpl tx = (TransactionImpl) t; 1056 1057 if (!dtmEnabled) 1058 { 1059 return tx.getLocalId(); 1060 } 1061 else 1062 { 1063 return tx.getPropagationContext(); 1064 } 1065 } 1066 1067 1069 public void registerWork(Work work, Xid xid, long timeout) 1070 throws WorkCompletedException 1071 { 1072 if (trace) 1073 log.trace("registering work=" + work + " xid=" + xid + 1074 " timeout=" + timeout); 1075 try 1076 { 1077 TransactionImpl tx = importExternalTransaction(xid, timeout); 1078 tx.setWork(work); 1079 } 1080 catch (WorkCompletedException e) 1081 { 1082 throw e; 1083 } 1084 catch (Throwable t) 1085 { 1086 WorkCompletedException e = 1087 new WorkCompletedException ("Error registering work", t); 1088 e.setErrorCode(WorkException.TX_RECREATE_FAILED); 1089 throw e; 1090 } 1091 if (trace) 1092 log.trace("registered work= " + work + " xid=" + xid + 1093 " timeout=" + timeout); 1094 } 1095 1096 public void startWork(Work work, Xid xid) 1097 throws WorkCompletedException 1098 { 1099 if (trace) 1100 log.trace("starting work=" + work + " xid=" + xid); 1101 TransactionImpl tx = getExternalTransaction(xid); 1102 associateThread(tx); 1103 if (trace) 1104 log.trace("started work= " + work + " xid=" + xid); 1105 } 1106 1107 public void endWork(Work work, Xid xid) 1108 { 1109 if (trace) 1110 log.trace("ending work=" + work + " xid=" + xid); 1111 try 1112 { 1113 TransactionImpl tx = getExternalTransaction(xid); 1114 tx.setWork(null); 1115 disassociateThread(); 1116 } 1117 catch (WorkCompletedException e) 1118 { 1119 log.error("Unexpected error from endWork ", e); 1120 throw new UnexpectedThrowable(e.toString()); 1121 } 1122 if (trace) 1123 log.trace("ended work=" + work + " xid=" + xid); 1124 } 1125 1126 public void cancelWork(Work work, Xid xid) 1127 { 1128 if (trace) 1129 log.trace("cancling work=" + work + " xid=" + xid); 1130 try 1131 { 1132 TransactionImpl tx = getExternalTransaction(xid); 1133 tx.setWork(null); 1134 } 1135 catch (WorkCompletedException e) 1136 { 1137 log.error("Unexpected error from cancelWork ", e); 1138 throw new UnexpectedThrowable(e.toString()); 1139 } 1140 if (trace) 1141 log.trace("cancled work=" + work + " xid=" + xid); 1142 } 1143 1144 public int prepare(Xid xid) 1145 throws XAException 1146 { 1147 if (trace) 1148 log.trace("preparing xid=" + xid); 1149 try 1150 { 1151 TransactionImpl tx = getExternalTransaction(xid); 1152 resume(tx); 1153 int result = tx.prepare(xid); 1154 if (trace) 1155 log.trace("prepared xid=" + xid + " result=" + result); 1156 return result; 1157 } 1158 catch (Throwable t) 1159 { 1160 JBossXAException.rethrowAsXAException("Error during prepare", t); 1161 throw new UnreachableStatementException(); 1162 } 1163 finally 1164 { 1165 try 1166 { 1167 suspend(); 1168 } 1169 catch (SystemException e) 1170 { 1171 JBossXAException.rethrowAsXAException("Error during prepare", e); 1172 throw new UnreachableStatementException(); 1173 } 1174 } 1175 } 1176 1177 public void rollback(Xid xid) 1178 throws XAException 1179 { 1180 if (trace) 1181 log.trace("rolling back xid=" + xid); 1182 try 1183 { 1184 TransactionImpl tx = getExternalTransaction(xid); 1185 tx.rollback(); 1186 } 1187 catch (Throwable t) 1188 { 1189 JBossXAException.rethrowAsXAException("Error during rollback", t); 1190 } 1191 if (trace) 1192 log.trace("rolled back xid=" + xid); 1193 } 1194 1195 public void commit(Xid xid, boolean onePhase) 1196 throws XAException 1197 { 1198 if (trace) 1199 log.trace("committing xid=" + xid + " onePhase=" + onePhase); 1200 try 1201 { 1202 TransactionImpl tx = getExternalTransaction(xid); 1203 tx.commit(onePhase); 1204 } 1205 catch (Throwable t) 1206 { 1207 JBossXAException.rethrowAsXAException("Error during commit", t); 1208 } 1209 if (trace) 1210 log.trace("committed xid=" + xid); 1211 } 1212 1213 public void forget(Xid xid) 1214 throws XAException 1215 { 1216 if (trace) 1217 log.trace("forgetting xid=" + xid); 1218 try 1219 { 1220 TransactionImpl tx = getExternalTransaction(xid); 1221 tx.forget(); 1222 } 1223 catch (Throwable t) 1224 { 1225 JBossXAException.rethrowAsXAException("Error during forget", t); 1226 } 1227 if (trace) 1228 log.trace("forgot xid=" + xid); 1229 } 1230 1231 public Xid [] recover(int flag) 1232 throws XAException 1233 { 1234 List xidList = new ArrayList (); 1235 Collection txCollection = localIdTx.values(); 1236 synchronized (localIdTx) 1237 { 1238 Iterator i = txCollection.iterator(); 1239 while (i.hasNext()) 1240 { 1241 TransactionImpl tx = (TransactionImpl) i.next(); 1242 if (tx.isPreparedOrHeuristicallyCompletedJCAInboundTx()) 1243 xidList.add(tx.getInboundXid()); 1244 } 1245 } 1246 return (Xid []) xidList.toArray(new Xid [xidList.size()]); 1247 } 1248 1249 1253 public TransactionImpl importExternalTransaction(int formatId, 1254 byte[] globalId, 1255 Coordinator coordinator, 1256 long txTimeOut) 1257 { 1258 GlobalId gid = new GlobalId(formatId, globalId); 1259 TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid); 1260 if (tx != null) 1261 { 1262 if (trace) 1263 log.trace("imported existing transaction gid: " + gid + 1264 " tx=" + tx); 1265 } 1266 else 1267 { 1268 ThreadInfo ti = getThreadInfo(); 1269 long timeout = (ti.timeout == 0) ? txTimeOut : ti.timeout; 1270 tx = new TransactionImpl(gid, coordinator, timeout); 1271 localIdTx.put(tx.getLocalId(), tx); 1272 if (globalIdsEnabled) 1273 globalIdTx.put(gid, tx); 1274 1275 if (trace) 1276 log.trace("imported new transaction gid: " + gid + " tx=" + tx + 1277 " timeout=" + timeout); 1278 } 1279 return tx; 1280 } 1281 1282 1286 TransactionImpl importExternalTransaction(Xid xid, long txTimeOut) 1287 { 1288 GlobalId gid = new GlobalId(xid.getFormatId(), 1289 xid.getGlobalTransactionId()); 1290 TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid); 1291 if (tx != null) 1292 { 1293 if (trace) 1294 log.trace("imported existing transaction gid: " + gid + 1295 " tx=" + tx); 1296 } 1297 else 1298 { 1299 ThreadInfo ti = getThreadInfo(); 1300 long timeout = (ti.timeout == 0) ? txTimeOut : ti.timeout; 1301 tx = new TransactionImpl(gid, xid.getBranchQualifier(), timeout); 1302 localIdTx.put(tx.getLocalId(), tx); 1303 if (globalIdsEnabled) 1304 globalIdTx.put(gid, tx); 1305 1306 if (trace) 1307 log.trace("imported new transaction gid: " + gid + " tx=" + tx + 1308 " timeout=" + timeout); 1309 } 1310 return tx; 1311 } 1312 1313 TransactionImpl getExternalTransaction(Xid xid) 1314 throws WorkCompletedException 1315 { 1316 GlobalId gid = new GlobalId(xid); 1317 TransactionImpl tx = (TransactionImpl) globalIdTx.get(gid); 1318 if (tx == null) 1319 throw new WorkCompletedException ("Xid not found " + xid, 1320 WorkException.TX_RECREATE_FAILED); 1321 return tx; 1322 } 1323 1324 1345 public void recreateTransaction(long localId, 1346 List pendingXAWorkList, 1347 TxCompletionHandler completionHandler, 1348 LogRecord.HeurData heurData) 1349 { 1350 LocalId localIdObject = new LocalId(localId); 1351 TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject); 1352 if (tx != null) 1353 { 1354 if (trace) 1355 log.trace("recreateTransaction called for existing transaction, " + 1356 "localId=" + localId + ", tx=" + tx, 1357 new Throwable ("[Stack trace]")); 1358 } 1359 else 1360 { 1361 tx = new TransactionImpl(localId, 1362 pendingXAWorkList, 1363 completionHandler, 1364 heurData); 1365 localIdTx.put(tx.getLocalId(), tx); 1366 if (globalIdsEnabled) 1367 globalIdTx.put(tx.getGlobalId(), tx); 1368 1369 if (trace) 1370 log.trace("recreated transaction with localId=" + localId + 1371 ", tx=" + tx + 1372 ", status=" + TxUtils.getStatusAsString(tx.getStatus())); 1373 } 1374 } 1375 1376 1401 public void recreateTransaction(long localId, 1402 List pendingXAWorkList, 1403 String [] resources, 1404 TxCompletionHandler completionHandler, 1405 LogRecord.HeurData heurData) 1406 { 1407 LocalId localIdObject = new LocalId(localId); 1408 TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject); 1409 if (tx != null) 1410 { 1411 if (trace) 1412 log.trace("recreateTransaction called for existing transaction, " + 1413 "localId=" + localId + ", tx=" + tx, 1414 new Throwable ("[Stack trace]")); 1415 } 1416 else 1417 { 1418 tx = new TransactionImpl(localId, 1419 pendingXAWorkList, 1420 resources, 1421 completionHandler, 1422 heurData); 1423 localIdTx.put(tx.getLocalId(), tx); 1424 if (globalIdsEnabled) 1425 globalIdTx.put(tx.getGlobalId(), tx); 1426 1427 if (trace) 1428 log.trace("recreated transaction with localId=" + localId + 1429 ", tx=" + tx + 1430 ", status=" + TxUtils.getStatusAsString(tx.getStatus())); 1431 } 1432 } 1433 1434 1461 public void recreateTransaction(long localId, 1462 int inboundFormatId, 1463 byte[] globalTransactionId, 1464 String recoveryCoord, 1465 List pendingXAWorkList, 1466 String [] resources, 1467 TxCompletionHandler completionHandler, 1468 LogRecord.HeurData heurData) 1469 { 1470 LocalId localIdObject = new LocalId(localId); 1471 TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject); 1472 if (tx != null) 1473 { 1474 if (trace) 1475 log.trace("recreateTransaction called for existing transaction, " + 1476 "localId=" + localId + ", tx=" + tx, 1477 new Throwable ("[Stack trace]")); 1478 } 1479 else 1480 { 1481 tx = new TransactionImpl(localId, 1482 inboundFormatId, 1483 globalTransactionId, 1484 recoveryCoord, 1485 pendingXAWorkList, 1486 resources, 1487 completionHandler, 1488 heurData); 1489 localIdTx.put(tx.getLocalId(), tx); 1490 if (globalIdsEnabled) 1491 globalIdTx.put(tx.getGlobalId(), tx); 1492 1493 if (trace) 1494 log.trace("recreated transaction with localId=" + localId + 1495 " tx=" + tx + 1496 ", status=" + TxUtils.getStatusAsString(tx.getStatus())); 1497 } 1498 } 1499 1500 1525 public void recreateTransaction(long localId, 1526 int inboundFormatId, 1527 byte[] globalTransactionId, 1528 byte[] inboundBranchQualifier, 1529 List pendingXAWorkList, 1530 String [] resources, 1531 TxCompletionHandler completionHandler, 1532 LogRecord.HeurData heurData) 1533 { 1534 LocalId localIdObject = new LocalId(localId); 1535 TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject); 1536 if (tx != null) 1537 { 1538 if (trace) 1539 log.trace("recreateTransaction called for existing transaction, " + 1540 "localId=" + localId + ", tx=" + tx, 1541 new Throwable ("[Stack trace]")); 1542 } 1543 else 1544 { 1545 tx = new TransactionImpl(localId, 1546 inboundFormatId, 1547 globalTransactionId, 1548 inboundBranchQualifier, 1549 pendingXAWorkList, 1550 resources, 1551 completionHandler, 1552 heurData); 1553 localIdTx.put(tx.getLocalId(), tx); 1554 if (globalIdsEnabled) 1555 globalIdTx.put(tx.getGlobalId(), tx); 1556 1557 if (trace) 1558 log.trace("recreated transaction with localId=" + localId + 1559 ", tx=" + tx + 1560 ", status=" + TxUtils.getStatusAsString(tx.getStatus())); 1561 } 1562 } 1563 1564 1580 public void recreateTransaction(LogRecord.HeurData heurData, 1581 List xaResourcesWithHeuristics, 1582 TxCompletionHandler completionHandler) 1583 { 1584 LocalId localIdObject = new LocalId(heurData.localTransactionId); 1585 TransactionImpl tx = (TransactionImpl) localIdTx.get(localIdObject); 1586 if (tx != null) 1587 { 1588 if (trace) 1589 log.trace("recreateTransaction called for existing transaction, " + 1590 "localId=" + heurData.localTransactionId + ", tx=" + tx + 1591 ", status=" + TxUtils.getStatusAsString(tx.getStatus()) + 1592 ", heuristicStatus=" + TxUtils.getXAErrorCodeAsString( 1593 heurData.heuristicStatusCode), 1594 new Throwable ("[Stack trace]")); 1595 } 1596 else 1597 { 1598 tx = new TransactionImpl(heurData, 1599 xaResourcesWithHeuristics, 1600 completionHandler); 1601 localIdTx.put(tx.getLocalId(), tx); 1602 if (globalIdsEnabled) 1603 globalIdTx.put(tx.getGlobalId(), tx); 1604 1605 if (trace) 1606 log.trace("recreated transaction with localId=" + 1607 heurData.localTransactionId + ", tx=" + tx + 1608 ", status=" + TxUtils.getStatusAsString(tx.getStatus()) + 1609 ", heuristicStatus=" + TxUtils.getXAErrorCodeAsString( 1610 heurData.heuristicStatusCode)); 1611 1612 } 1617 } 1618 1619 1621 public void lock(TransactionLocal local, Transaction tx) throws InterruptedException 1622 { 1623 TransactionImpl tximpl = (TransactionImpl) tx; 1624 tximpl.lock(); 1625 } 1626 1627 public void unlock(TransactionLocal local, Transaction tx) 1628 { 1629 TransactionImpl tximpl = (TransactionImpl) tx; 1630 tximpl.unlock(); 1631 } 1632 1633 public Object getValue(TransactionLocal local, Transaction tx) 1634 { 1635 TransactionImpl tximpl = (TransactionImpl) tx; 1636 return tximpl.getTransactionLocalValue(local); 1637 } 1638 1639 public void storeValue(TransactionLocal local, Transaction tx, Object value) 1640 { 1641 TransactionImpl tximpl = (TransactionImpl) tx; 1642 tximpl.putTransactionLocalValue(local, value); 1643 } 1644 1645 public boolean containsValue(TransactionLocal local, Transaction tx) 1646 { 1647 TransactionImpl tximpl = (TransactionImpl) tx; 1648 return tximpl.containsTransactionLocal(local); 1649 } 1650 1651 1653 public Resource stringToResource(String strResource) 1654 { 1655 return TransactionImpl.stringToResource(strResource); 1656 } 1657 1658 public RecoveryCoordinator stringToRecoveryCoordinator( 1659 String strRecCoordinator) 1660 { 1661 return TransactionImpl.stringToRecoveryCoordinator(strRecCoordinator); 1662 } 1663 1664 public String resourceToString(Resource res) 1665 { 1666 return TransactionImpl.resourceToString(res); 1667 } 1668 1669 public String recoveryCoordinatorToString(RecoveryCoordinator recoveryCoord) 1670 { 1671 return TransactionImpl.recoveryCoordinatorToString(recoveryCoord); 1672 } 1673 1674 1676 1679 public void setDTMEnabled(boolean newValue) 1680 { 1681 if (newValue == true && !globalIdsEnabled) 1682 { 1683 setGlobalIdsEnabled(newValue); 1685 } 1686 dtmEnabled = newValue; 1687 } 1688 1689 1692 public void setDTMCoordinatorFactory( 1693 CoordinatorFactory dtmCoordinatorFactory) 1694 { 1695 TransactionImpl.setDTMCoordinatorFactory(dtmCoordinatorFactory); 1696 } 1697 1698 1701 public void setDTMResourceFactory(ResourceFactory dtmResourceFactory) 1702 { 1703 TransactionImpl.setDTMResourceFactory(dtmResourceFactory); 1704 } 1705 1706 1709 public void setOTSResourceFactory(ResourceFactory otsResourceFactory) 1710 { 1711 TransactionImpl.setOTSResourceFactory(otsResourceFactory); 1712 } 1713 1714 1717 public void setOTSContextFactory(OTSContextFactory otsContextFactory) 1718 { 1719 TransactionImpl.setOTSContextFactory(otsContextFactory); 1720 } 1721 1722 1725 public void setInterpositionEnabled(boolean newValue) 1726 { 1727 TransactionImpl.setInterpositionEnabled(newValue); 1728 } 1729 1730 1733 public boolean getInterpositionEnabled() 1734 { 1735 return TransactionImpl.getInterpositionEnabled(); 1736 } 1737 1738 public void setDTMStringRemoteRefConverter( 1739 StringRemoteRefConverter otsStrRemoteRefConverter) 1740 { 1741 TransactionImpl.setDTMStrRemoteRefConverter(otsStrRemoteRefConverter); 1742 } 1743 1744 public void setOTSStringRemoteRefConverter( 1745 StringRemoteRefConverter otsStrRemoteRefConverter) 1746 { 1747 TransactionImpl.setOTSStrRemoteRefConverter(otsStrRemoteRefConverter); 1748 } 1749 1750 1752 1755 void releaseTransactionImpl(TransactionImpl tx) 1756 { 1757 localIdTx.remove(tx.getLocalId()); 1758 if (globalIdsEnabled) 1759 globalIdTx.remove(tx.getGlobalId()); 1760 } 1761 1762 1765 void incCommitCount() 1766 { 1767 ++commitCount; 1768 } 1769 1770 1773 void incRollbackCount() 1774 { 1775 ++rollbackCount; 1776 } 1777 1778 1780 1782 1787 private ThreadLocal threadTx = new ThreadLocal (); 1788 1789 1793 private Map localIdTx = Collections.synchronizedMap(new HashMap ()); 1794 1795 1796 1800 private Map globalIdTx = Collections.synchronizedMap(new HashMap ()); 1801 1802 1803 1807 private ThreadInfo getThreadInfo() 1808 { 1809 ThreadInfo ret = (ThreadInfo) threadTx.get(); 1810 1811 if (ret == null) 1812 { 1813 ret = new ThreadInfo(); 1814 ret.timeout = timeOut; 1815 threadTx.set(ret); 1816 } 1817 1818 return ret; 1819 } 1820 1821 1823 1827 static class ThreadInfo 1828 { 1829 long timeout; 1830 TransactionImpl tx; 1831 } 1832 1833} 1834 | Popular Tags |