1 49 package org.objectweb.jotm; 50 51 import java.io.Serializable ; 52 import java.util.Collections ; 53 import java.util.Date ; 54 import java.util.EmptyStackException ; 55 import java.util.HashMap ; 56 import java.util.Iterator ; 57 import java.util.List ; 58 import java.util.Map ; 59 import java.util.Set ; 60 import java.util.Stack ; 61 import java.util.Vector ; 62 63 import javax.naming.NamingException ; 64 import javax.naming.Reference ; 65 import javax.naming.Referenceable ; 66 import javax.naming.StringRefAddr ; 67 import javax.resource.spi.XATerminator ; 68 import javax.transaction.HeuristicMixedException ; 69 import javax.transaction.HeuristicRollbackException ; 70 import javax.transaction.InvalidTransactionException ; 71 import javax.transaction.NotSupportedException ; 72 import javax.transaction.RollbackException ; 73 import javax.transaction.Status ; 74 import javax.transaction.SystemException ; 75 import javax.transaction.Transaction ; 76 import javax.transaction.UserTransaction ; 77 import javax.transaction.xa.XAException ; 78 import javax.transaction.xa.XAResource ; 79 80 import org.objectweb.transaction.jta.ResourceManagerEvent; 81 import org.objectweb.transaction.jta.TransactionManager; 82 import org.objectweb.howl.log.xa.XACommittingTx; 83 84 100 101 public class Current implements UserTransaction , TransactionManager, Referenceable , Serializable { 102 103 private transient static ThreadLocal threadTx = new ThreadLocal (); 106 107 111 private transient static Map txXids = Collections.synchronizedMap(new HashMap ()); 113 114 private transient static Current unique = null; 116 117 private transient static TimerManager timermgr = null; private transient static TransactionFactory tm = null; private transient static TransactionRecovery tr = null; 122 private static final String JOTM_VERSION = "JOTM 2.0.10"; 123 private static final int DEFAULT_TIMEOUT = 60; 124 private int defaultTimeout = DEFAULT_TIMEOUT; 125 private int transactionTimeout = DEFAULT_TIMEOUT; 126 private static final boolean DEFAULT_RECOVERY = false; 127 private static boolean transactionRecovery = DEFAULT_RECOVERY; 128 129 private transient int nb_bg_tx = 0; 131 private transient int nb_rb_tx = 0; 132 private transient int nb_cm_tx = 0; 133 private transient int nb_to = 0; 134 135 139 143 144 public Current(){ 145 TraceTm.jta.info(JOTM_VERSION); 146 147 if (TraceTm.jta.isDebugEnabled()) { 148 TraceTm.jta.debug("no args constructor"); 149 } 150 151 unique = this; 152 timermgr = TimerManager.getInstance(); 153 154 try { 155 tr = new TransactionRecoveryImpl (); 156 } catch (Exception e) { 157 setDefaultRecovery(false); 158 TraceTm.recovery.error("Cannot open Howl Log"); 159 TraceTm.recovery.error("JOTM Recovery is being disabled"); 160 } 161 } 162 163 171 172 public Current(TransactionFactory tmfact){ 173 TraceTm.jta.info(JOTM_VERSION); 174 175 if (TraceTm.jta.isDebugEnabled()) { 176 TraceTm.jta.debug("TransactionFactory="+ tmfact); 177 } 178 179 unique = this; 180 tm = tmfact; 181 182 timermgr = TimerManager.getInstance(); 183 184 try { 185 tr = new TransactionRecoveryImpl (); 186 } catch (Exception e) { 187 setDefaultRecovery(false); 188 TraceTm.recovery.error("Cannot open Howl Log"); 189 TraceTm.recovery.error("JOTM Recovery is being disabled"); 190 } 191 } 192 193 198 199 public static TransactionManager getTransactionManager() { 200 return (TransactionManager) unique; 201 } 202 203 207 217 218 public void begin() throws NotSupportedException , SystemException { 219 220 if (TraceTm.jta.isDebugEnabled()) { 221 TraceTm.jta.debug("begin transaction"); 222 } 223 224 TransactionImpl tx = (TransactionImpl) threadTx.get(); 226 227 if (TraceTm.jta.isDebugEnabled()) { 228 TraceTm.jta.debug("threadTx.get= " + threadTx.toString()); 229 } 230 231 if (tx != null) { 232 if (txXids.containsValue(tx)) { 233 throw new NotSupportedException ("Nested transactions not supported"); 234 } else { 235 if (TraceTm.jta.isDebugEnabled()) { 236 TraceTm.jta.debug("Resetting current tx = " + tx + " since it is already completed."); 237 } 238 } 239 } 240 241 XidImpl otid = new XidImpl(); 244 245 tx = new TransactionImpl(otid, transactionTimeout); 248 249 if (TraceTm.jta.isDebugEnabled()) { 250 TraceTm.jta.debug("tx=" + tx); 251 } 252 253 try { 255 tx.doAttach(XAResource.TMJOIN); 256 } catch (RollbackException e) { 257 TraceTm.jotm.error("doAttach: RollbackException"); 259 throw new SystemException ("RollbackException in occured in begin() " + e.getMessage()); 260 } 261 262 threadTx.set(tx); 264 265 if (TraceTm.jta.isDebugEnabled()) { 266 TraceTm.jta.debug("threadTx.set= " + threadTx.toString()); 267 } 268 269 putTxXid(otid, tx); 271 272 if (timermgr != null) { 274 tx.setTimer(timermgr.addTimer(tx, transactionTimeout, null, false)); 275 } 276 277 Date myDate = new Date (); 279 tx.setTxDate(myDate.toString()); 280 281 Stack curStack = (Stack ) eventListStack.get(); 284 285 if (curStack != null) { 287 try { 288 List list = (List ) curStack.peek(); 289 290 if (list != null) { 291 292 for (Iterator it = list.iterator(); it.hasNext();) { 293 ((ResourceManagerEvent) it.next()).enlistConnection(tx); 294 } 295 } else { 296 297 if (TraceTm.jta.isDebugEnabled()) { 298 TraceTm.jta.debug("Current.begin called with null list"); 299 } 300 } 301 } catch (EmptyStackException e) { 302 if (TraceTm.jta.isDebugEnabled()) { 303 TraceTm.jta.debug("Current.begin called with empty stack"); 304 } 305 } 306 } 307 } 308 309 313 325 326 public void begin(javax.transaction.xa.Xid passxid) throws NotSupportedException , SystemException { 327 begin(passxid, (long) transactionTimeout); 328 } 329 330 345 346 public void begin(javax.transaction.xa.Xid passxid, long timeout) throws NotSupportedException , SystemException { 347 348 if (TraceTm.jta.isDebugEnabled()) { 349 TraceTm.jta.debug("begin inflow transaction, timeout = " + timeout); 350 } 351 352 if (timeout <= 0) { 353 timeout = defaultTimeout; 354 } 355 356 TransactionImpl tx = (TransactionImpl) threadTx.get(); 358 359 if (TraceTm.jta.isDebugEnabled()) { 360 TraceTm.jta.debug("threadTx.get= " + threadTx.toString()); 361 } 362 363 if (tx != null) { 364 if (txXids.containsValue(tx)) { 365 throw new NotSupportedException ("Nested transactions not supported"); 366 } else { 367 if (TraceTm.jta.isDebugEnabled()) { 368 TraceTm.jta.debug("Resetting current tx = " + tx + " since it is already completed."); 369 } 370 } 371 } 372 373 XidImpl pxid = new XidImpl(passxid); 375 376 tx = new TransactionImpl(pxid, (int) timeout); 379 380 if (TraceTm.jta.isDebugEnabled()) { 381 TraceTm.jta.debug("tx=" + tx); 382 } 383 384 threadTx.set(tx); 386 387 if (TraceTm.jta.isDebugEnabled()) { 388 TraceTm.jta.debug("threadTx.set= " + threadTx.toString()); 389 } 390 391 putTxXid(pxid, tx); 393 394 if (timermgr != null) { 396 tx.setTimer(timermgr.addTimer(tx, (int) timeout, null, false)); 397 } 398 399 Date myDate = new Date (); 401 tx.setTxDate(myDate.toString()); 402 } 403 404 416 417 public XATerminator getXATerminator() throws XAException { 418 419 XATerminator xaterm = null; 420 421 try { 422 xaterm = new XATerminatorImpl(); 423 } catch (XAException e) { 424 if (TraceTm.jta.isDebugEnabled()) { 425 TraceTm.jta.debug("Cannot create XATerminatorImpl"+ e); 426 } 427 } 428 429 return xaterm; 430 } 431 432 436 437 461 462 public void commit() 463 throws 464 RollbackException , 465 HeuristicMixedException , 466 HeuristicRollbackException , 467 SecurityException , 468 IllegalStateException , 469 SystemException { 470 471 if (TraceTm.jta.isDebugEnabled()) { 472 TraceTm.jta.debug("commit transaction "); 473 } 474 475 TransactionImpl tx = (TransactionImpl) getTransaction(); 477 478 if (tx == null) { 479 throw new IllegalStateException ("Cannot get Transaction for commit"); 480 } 481 482 if (TraceTm.jta.isDebugEnabled()) { 483 TraceTm.jta.debug("tx=" + tx); 484 } 485 486 try { 488 tx.commit(); 489 } finally { 490 threadTx.set(null); 494 495 transactionTimeout = defaultTimeout; 497 498 if (TraceTm.jta.isDebugEnabled()) { 499 TraceTm.jta.debug("threadTx.set= null"); 500 TraceTm.jta.debug("reset timeout= " + defaultTimeout); 501 } 502 } 503 } 504 505 518 public void rollback() throws IllegalStateException , SecurityException , SystemException { 519 520 if (TraceTm.jta.isDebugEnabled()) { 521 TraceTm.jta.debug("Current.rollback()"); 522 } 523 524 TransactionImpl tx = (TransactionImpl) getTransaction(); 526 527 if (tx == null) { 528 throw new IllegalStateException ("Cannot get Transaction for rollback"); 529 } 530 531 threadTx.set(null); 532 533 if (TraceTm.jta.isDebugEnabled()) { 534 TraceTm.jta.debug("threadTx.set= null"); 535 } 536 537 tx.rollback(); 539 540 if (TraceTm.jta.isDebugEnabled()) { 541 TraceTm.jta.debug("reset timeout= " + defaultTimeout); 542 } 543 544 transactionTimeout = defaultTimeout; 545 546 } 547 548 558 559 public void setRollbackOnly() throws IllegalStateException , SystemException { 560 561 if (TraceTm.jta.isDebugEnabled()) { 562 TraceTm.jta.debug("Current.setRollbackOnly()"); 563 } 564 TransactionImpl tx = (TransactionImpl) getTransaction(); 566 567 if (tx == null) { 568 throw new IllegalStateException ("Cannot get Transaction for setRollbackOnly"); 569 } 570 571 tx.setRollbackOnly(); 573 } 574 575 585 586 public int getStatus() throws SystemException { 587 588 if (TraceTm.jta.isDebugEnabled()) { 589 TraceTm.jta.debug("Current.getStatus()"); 590 } 591 592 TransactionImpl tx = (TransactionImpl) getTransaction(); 594 595 if (tx == null) { 596 return Status.STATUS_NO_TRANSACTION; 597 } 598 599 return tx.getStatus(); 601 } 602 603 616 617 public void setTransactionTimeout(int timeout) throws SystemException { 618 619 if (TraceTm.jta.isDebugEnabled()) { 620 TraceTm.jta.debug("timeout= "+ timeout); 621 } 622 623 627 TransactionImpl tx = (TransactionImpl) threadTx.get(); 628 629 if (tx != null) { 630 if (txXids.containsValue(tx)) { 631 if (TraceTm.jta.isDebugEnabled()) { 632 TraceTm.jta.debug("Cannot reset transaction timeout, tx in execution"); 633 } 634 return; 636 } 637 } 638 639 if (timeout > 0) { 640 transactionTimeout = timeout; 641 } else { 642 transactionTimeout = defaultTimeout; 643 } 644 645 if (TraceTm.jta.isDebugEnabled()) { 646 TraceTm.jta.debug("Resetting transaction timeout= " + transactionTimeout); 647 } 648 } 649 650 663 664 public void setTransactionRecovery(boolean recovery) throws SystemException { 665 666 if (TraceTm.recovery.isDebugEnabled()) { 667 TraceTm.recovery.debug("recovery="+ recovery); 668 } 669 670 if (recovery) { 671 transactionRecovery = recovery; 672 } else { 673 transactionRecovery = DEFAULT_RECOVERY; 674 } 675 } 676 677 682 694 695 public Transaction getTransaction() throws SystemException { 696 Transaction ret = (Transaction ) threadTx.get(); 697 698 if (TraceTm.jta.isDebugEnabled()) { 699 TraceTm.jta.debug("threadTx.get= " + threadTx.toString()); 700 TraceTm.jta.debug("Transaction ret= " + ret); 701 } 702 703 return ret; 704 } 705 706 732 733 public void resume(Transaction tobj) throws InvalidTransactionException , IllegalStateException , SystemException { 734 735 if (TraceTm.jta.isDebugEnabled()) { 736 TraceTm.jta.debug("resume transaction"); 737 } 738 739 if (tobj == null) { 741 TraceTm.jotm.error("resume: null arg."); 742 throw new InvalidTransactionException ("resume(null) is not valid"); 743 } 744 745 if (TraceTm.jta.isDebugEnabled()) { 746 TraceTm.jta.debug("tx="+ tobj); 747 } 748 749 Transaction mytx = (Transaction ) threadTx.get(); 751 752 if (TraceTm.jta.isDebugEnabled()) { 753 TraceTm.jta.debug("threadTx.get= " + threadTx.toString()); 754 } 755 756 if (mytx != null) { 757 if (mytx.equals(tobj)) { 758 if (TraceTm.jta.isDebugEnabled()) { 759 TraceTm.jta.debug("nothing to do"); 760 } 761 return; 762 } 763 TraceTm.jotm.error("resume: already associated with another transaction."); 764 throw new IllegalStateException ("the thread is already associated with another transaction."); 765 } 766 767 if (!(tobj instanceof TransactionImpl)) { 769 TraceTm.jotm.error("resume: non TransactionImpl arg."); 770 throw new InvalidTransactionException ("resume(" + tobj.getClass().getName() + ") is not valid"); 771 } 772 773 threadTx.set(tobj); 775 776 if (TraceTm.jta.isDebugEnabled()) { 777 TraceTm.jta.debug("threadTx.set= " + threadTx.toString()); 778 } 779 780 try { 782 ((TransactionImpl) tobj).doAttach(XAResource.TMRESUME); 783 } catch (RollbackException e) { 784 TraceTm.jotm.error("RollbackException occured in resume()"); 786 throw new SystemException ("RollbackException in occured in resume() " + e.getMessage()); 787 } 788 } 789 790 815 816 public Transaction suspend() throws SystemException { 817 818 if (TraceTm.jta.isDebugEnabled()) { 819 TraceTm.jta.debug("suspend transaction"); 820 } 821 822 TransactionImpl tx = (TransactionImpl) threadTx.get(); 824 825 if (TraceTm.jta.isDebugEnabled()) { 826 TraceTm.jta.debug("threadTx.get= " + threadTx.toString()); 827 } 828 829 if (tx != null) { 830 831 if (TraceTm.jta.isDebugEnabled()) { 832 TraceTm.jta.debug("tx="+ tx); 833 } 834 835 tx.doDetach(XAResource.TMSUSPEND); 836 threadTx.set(null); 837 838 if (TraceTm.jta.isDebugEnabled()) { 839 TraceTm.jta.debug("threadTx.set= null"); 840 } 841 } 842 843 return tx; 844 } 845 846 851 854 855 public void connectionOpened(ResourceManagerEvent event) { 856 857 if (TraceTm.jta.isDebugEnabled()) { 858 TraceTm.jta.debug("Current.connectionOpened " + this); 859 } 860 861 List list = null; 862 Stack curStack = (Stack ) eventListStack.get(); 863 865 if (curStack == null) { 866 eventListStack.set(curStack = new Stack ()); 868 } else { try { 870 list = (List ) curStack.pop(); 871 } catch (EmptyStackException e) { 872 } 874 } 875 876 if (list == null) 878 list = new Vector (1); 879 880 list.add(event); 882 883 if (TraceTm.jta.isDebugEnabled()) { 884 TraceTm.jta.debug("list.add(event) = " + event); 885 } 886 887 curStack.push(list); 889 } 890 891 894 895 public void connectionClosed(ResourceManagerEvent event) { 896 897 if (TraceTm.jta.isDebugEnabled()) { 898 TraceTm.jta.debug("Current.connectionClosed, remove"); 899 } 900 901 removeFromCurrentStack(event); 903 } 904 905 908 909 public void connectionErrorOccured(ResourceManagerEvent event) { 910 911 if (TraceTm.jta.isDebugEnabled()) { 912 TraceTm.jta.debug("Current.connectionErrorOccured"); 913 } 914 915 removeFromCurrentStack(event); } 917 918 private void removeFromCurrentStack(ResourceManagerEvent event) { 919 920 if (TraceTm.jta.isDebugEnabled()) { 921 TraceTm.jta.debug("Current.removeFromCurrentStack " + event); 922 TraceTm.jta.debug("Current = " + this); 923 } 924 925 Stack curStack = (Stack ) eventListStack.get(); 926 928 if (curStack == null) { 929 return; 932 } 933 934 try { 935 936 List list = (List ) curStack.peek(); 937 938 if (list != null) { 939 941 list.remove(event); 942 } 943 } catch (EmptyStackException e) { 944 } 946 } 947 948 952 954 private transient ThreadLocal eventListStack = new ThreadLocal (); 955 956 959 960 public void pushThreadLocalRMEventList(List eventList) { 961 962 if (TraceTm.jta.isDebugEnabled()) { 963 TraceTm.jta.debug("Current.pushThreadLocalRMEventList"); 964 } 965 966 Stack curStack = (Stack ) eventListStack.get(); 967 968 if (curStack == null) { 969 eventListStack.set(curStack = new Stack ()); 970 } 971 972 curStack.push(eventList); 973 } 974 975 978 979 public List popThreadLocalRMEventList() { 980 981 if (TraceTm.jta.isDebugEnabled()) { 982 TraceTm.jta.debug("Current.popThreadLocalRMEventList"); 983 } 984 985 Stack curStack = (Stack ) eventListStack.get(); 986 return (List ) curStack.pop(); 987 } 988 989 993 1000 1001 public Reference getReference() throws NamingException { 1002 1003 if (TraceTm.jta.isDebugEnabled()) { 1004 TraceTm.jta.debug("Current.getReference()"); 1005 } 1006 1007 Reference ref = new Reference (this.getClass().getName(), "org.objectweb.jotm.UserTransactionFactory", null); 1009 Integer i = new Integer (transactionTimeout); 1010 ref.add(new StringRefAddr ("jotm.timeout", i.toString())); 1011 return ref; 1012 } 1013 1014 1018 1024 1025 public static Current getCurrent() { 1026 1027 return unique; 1028 } 1029 1030 1035 1036 public static TransactionFactory getJTM() { 1037 1038 if (tm == null) { 1039 TraceTm.jotm.error("Current: TMFactory is null!"); 1040 } 1041 1042 return tm; 1043 } 1044 1045 1050 1051 public static TransactionRecovery getTransactionRecovery() { 1052 1053 if (tr == null) { 1054 TraceTm.jotm.error("Current: Transaction Recovery is null!"); 1055 } 1056 1057 return tr; 1058 } 1059 1060 1065 1066 public void setDefaultTimeout(int timeout) { 1067 1068 if (TraceTm.jta.isDebugEnabled()) { 1069 TraceTm.jta.debug("timeout= " + timeout); 1070 } 1071 1072 if (timeout != 0) { 1073 defaultTimeout = timeout; 1074 } 1075 1076 if (TraceTm.jta.isDebugEnabled()) { 1077 TraceTm.jta.debug("default timeout= " + defaultTimeout); 1078 } 1079 1080 } 1081 1082 1087 1088 public int getDefaultTimeout() { 1089 1090 return defaultTimeout; 1091 } 1092 1093 1098 1099 public static void setDefaultRecovery(boolean recovery) { 1100 1101 TraceTm.recovery.info("Jotm Recovery= " + recovery); 1102 1103 transactionRecovery = recovery; 1104 } 1105 1106 1111 1112 public static boolean getDefaultRecovery() { 1113 1114 return transactionRecovery; 1115 } 1116 1117 1133 1134 public void setPropagationContext(TransactionContext pctx, boolean isReply) { 1135 1136 if (TraceTm.jotm.isDebugEnabled()) { 1137 TraceTm.jotm.debug("pctx=" + pctx + ", isReply=" + isReply); 1138 } 1139 1140 if (pctx == null) { 1142 if (TraceTm.jta.isDebugEnabled()) { 1143 TraceTm.jta.debug("detach tx"); 1144 } 1145 1146 TransactionImpl tx = (TransactionImpl) threadTx.get(); 1147 1148 if (TraceTm.jta.isDebugEnabled()) { 1149 TraceTm.jta.debug("threadTx.get= " + threadTx.toString()); 1150 } 1151 1152 if (tx != null) { 1153 1156 if (tx.isRemovable()) { 1157 forgetTx(tx.getXid()); 1158 } 1159 1160 threadTx.set(null); 1162 1163 if (TraceTm.jta.isDebugEnabled()) { 1164 TraceTm.jta.debug("threadTx.set= null"); 1165 } 1166 } 1167 1168 return; 1169 } 1170 1171 Xid xid = pctx.getXid(); 1173 TransactionImpl tx = getTxXid(xid); 1174 1175 if (tx == null) { 1176 1177 if (!isReply) { 1179 if (TraceTm.jta.isDebugEnabled()) { 1180 TraceTm.jta.debug("new Tx"); 1181 } 1182 1183 tx = new TransactionImpl(pctx); 1184 putTxXid(xid, tx); 1185 1186 Date myDate = new Date (); 1188 tx.setTxDate(myDate.toString()); 1189 1190 } else { 1191 1192 1195 if (TraceTm.jta.isDebugEnabled()) { 1196 TraceTm.jta.debug("unknown tx:" + xid); 1197 } 1198 } 1199 1200 } else { 1201 1202 if (isReply) { 1203 1207 if (TraceTm.jta.isDebugEnabled()) { 1208 TraceTm.jta.debug("updating Xid=" + xid); 1209 } 1210 1211 tx.updatePropagationContext(pctx); 1212 } else { 1213 1214 if (TraceTm.jta.isDebugEnabled()) { 1215 TraceTm.jta.debug("transaction already known:" + xid); 1216 } 1217 } 1218 } 1219 1220 1224 if (!isReply) { 1225 threadTx.set(tx); 1226 1227 if (TraceTm.jta.isDebugEnabled()) { 1228 TraceTm.jta.debug("threadTx.set= " + threadTx.toString()); 1229 } 1230 } 1231 } 1232 1233 1237 1238 public TransactionContext getPropagationContext(boolean hold) { 1239 1240 if (TraceTm.jotm.isDebugEnabled()) { 1241 TraceTm.jotm.debug("hold=" + hold); 1242 } 1243 1244 try { 1245 TransactionImpl tx = (TransactionImpl) getTransaction(); 1246 1247 if (tx != null) { return tx.getPropagationContext(hold); 1249 } 1250 } catch (SystemException e) { 1251 TraceTm.jotm.error("getPropagationContext system exception:", e); 1252 } 1253 1254 return null; 1255 } 1256 1257 1264 1265 public void forgetTx(Xid xid) { 1266 1267 1269 TransactionImpl txCur = (TransactionImpl) txXids.get (xid); 1270 1271 if (txCur != null && txCur.equals((TransactionImpl) threadTx.get())) { 1272 threadTx.set(null); 1273 1274 if (TraceTm.jta.isDebugEnabled()) { 1275 TraceTm.jta.debug("threadTx.set = null"); 1276 } 1277 } 1278 removeTxXid(xid); 1279 } 1280 1281 1286 1287 public TransactionImpl getTxByXid(Xid xid) { 1288 1289 TransactionImpl tx = (TransactionImpl) txXids.get (xid); 1290 return tx; 1291 } 1292 1293 1298 1299 public javax.transaction.xa.Xid [] getPreparedHeuristicXid() { 1300 1301 Vector xidlist; 1302 int xidcount; 1303 javax.transaction.xa.Xid xid = null; 1304 1305 xidcount = txXids.size(); 1306 1307 if (xidcount == 0) { 1308 return null; 1309 } 1310 1311 xidlist = new Vector (); 1312 1313 Set txXidsSet = txXids.keySet(); 1314 1315 synchronized(txXids) { 1316 1317 Iterator txXidsIterator = txXidsSet.iterator(); 1318 1319 while (txXidsIterator.hasNext()){ 1320 TransactionImpl tx = (TransactionImpl) txXids.get(txXidsIterator.next()); 1321 1322 try { 1323 1324 if (tx.getStatus() == Status.STATUS_PREPARED) { 1325 xid = (javax.transaction.xa.Xid ) tx.getXid(); 1326 xidlist.add(xid); 1327 } 1328 } catch (SystemException e) { 1329 TraceTm.jotm.error("getPreparedHeuristicsXid system exception:", e); 1330 } 1331 } 1332 } 1333 1334 Vector mytxrecovered = JotmRecovery.getTxRecovered(); 1335 1336 return (javax.transaction.xa.Xid []) xidlist.toArray(); 1337 } 1338 1339 1344 1345 public javax.transaction.xa.Xid [] getAllXid() { 1346 1347 Vector xidlist; 1348 int xidcount; 1349 javax.transaction.xa.Xid xid = null; 1350 1351 xidcount = txXids.size(); 1352 1353 if (xidcount == 0) { 1354 return null; 1355 } 1356 1357 xidlist = new Vector (); 1358 1359 Set txXidsSet = txXids.keySet(); 1360 1361 synchronized(txXids) { 1362 1363 Iterator txXidsIterator = txXidsSet.iterator(); 1364 1365 while (txXidsIterator.hasNext()){ 1366 TransactionImpl mytx = (TransactionImpl) txXids.get(txXidsIterator.next()); 1367 xid = (javax.transaction.xa.Xid ) mytx.getXid(); 1368 xidlist.add(xid); 1369 } 1370 } 1371 1372 return (javax.transaction.xa.Xid []) xidlist.toArray(); 1373 } 1374 1375 1380 1381 public String [] getAllTx() { 1382 1383 Vector txList; 1384 List txResourceList; 1385 int txCount; 1386 int txResourceCount; 1387 String txStatusName; 1388 1389 txCount = txXids.size(); 1390 1391 if (txCount == 0) { 1392 return null; 1393 } 1394 1395 txList = new Vector (); 1396 1397 Set txXidsSet = txXids.keySet(); 1398 1399 synchronized(txXids) { 1400 1401 Iterator txXidsIterator = txXidsSet.iterator(); 1402 1403 while (txXidsIterator.hasNext()){ 1404 TransactionImpl mytx = (TransactionImpl) txXids.get(txXidsIterator.next()); 1405 1406 try { 1407 txStatusName = StatusHelper.getStatusName (mytx.getStatus()); 1408 } catch (SystemException e) { 1409 txStatusName = "No State Defined"; 1410 } 1411 1412 txResourceList = mytx.getEnlistedXAResource(); 1413 txResourceCount = txResourceList.size(); 1414 1415 if (txResourceCount == 0) { 1416 txList.add(mytx.getTxDate() + "????" + 1417 mytx.toString() + "????" + 1418 "NO Resource Defined" + "????" + 1419 txStatusName); 1420 } else { 1421 1422 for (int i=0; i < txResourceCount; i++) { 1423 txList.add(mytx.getTxDate() + "????" + 1424 mytx.toString() + "????" + 1425 txResourceList.get(i).toString() + "????" + 1426 txStatusName); 1427 } 1428 } 1429 } 1430 } 1431 1432 String [] myTxString = new String [txCount] ; 1433 1434 for (int i=0; i < txCount; i++) { 1435 myTxString[i] = txList.get(i).toString(); 1436 } 1437 1438 return myTxString; 1439 } 1440 1441 1446 1447 public String [] getAllRcTx() { 1448 1449 Vector vTxRecovered = null; 1450 Vector txList; 1451 int txCount; 1452 1453 JotmRecovery myjr = null; 1454 1455 if (tr == null) { 1456 if (TraceTm.recovery.isDebugEnabled()) { 1457 TraceTm.recovery.debug("tr= null"); 1458 } 1459 return null; 1460 } 1461 1462 myjr = tr.getJotmRecovery(); 1463 1464 if (myjr == null) { 1465 return null; 1466 } 1467 1468 vTxRecovered = JotmRecovery.getTxRecovered(); 1469 1470 txCount = vTxRecovered.size(); 1471 1472 if (TraceTm.recovery.isDebugEnabled()) { 1473 TraceTm.recovery.debug("txcount= " + txCount); 1474 } 1475 1476 if (txCount == 0) { 1477 return null; 1478 } 1479 1480 txList = new Vector (); 1481 TxRecovered mytxRecovered = null; 1482 1483 for (int i=0; i<txCount; i++){ 1484 mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i); 1485 1486 Xid temptxxid = new XidImpl(mytxRecovered.gettxxid()); 1487 1488 1493 txList.add(new String (mytxRecovered.gettxxid()) + "????" + 1494 temptxxid.toString() + "????" + 1495 mytxRecovered.gettxdatetime() + "????" + 1496 mytxRecovered.getxidcount()); 1497 } 1498 1499 String [] myTxString = new String [txCount] ; 1500 1501 for (int i=0; i < txCount; i++) { 1502 myTxString[i] = txList.get(i).toString(); 1503 } 1504 1505 return myTxString; 1506 } 1507 1508 1513 1514 public String [] getAllXaTx(String stx) { 1515 1516 Vector xaList; 1517 Vector rmList; 1518 int txCount; 1519 int rmiCount; 1520 int myxacount = 0; 1521 boolean mytxfound = false; 1522 boolean myrmifound = false; 1523 boolean myrmregistered = false; 1524 boolean myxaresfound = false; 1525 String mytxstatusname; 1526 1527 JotmRecovery myjr = null; 1528 1529 if (tr == null) { 1530 return null; 1531 } 1532 1533 myjr = tr.getJotmRecovery(); 1534 1535 if (myjr == null) { 1536 if (TraceTm.recovery.isDebugEnabled()) { 1537 TraceTm.recovery.debug("myjr= null"); 1538 } 1539 return null; 1540 } 1541 1542 xaList = new Vector (); 1543 TxxidRecovered mytxxidRecovered = null; 1544 TxRecovered mytxRecovered = null; 1545 Vector vTxRecovered = null; 1546 Vector vRecoverRmInfo = null; 1547 RmRegistration myRmRegistration = null; 1548 String myxares = null; 1549 1550 vTxRecovered = JotmRecovery.getTxRecovered(); 1551 1552 txCount = vTxRecovered.size(); 1553 1554 if (TraceTm.recovery.isDebugEnabled()) { 1555 TraceTm.recovery.debug("txcount= " + txCount); 1556 } 1557 1558 for (int i=0; i<txCount; i++){ 1559 mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i); 1560 1561 if (TraceTm.recovery.isDebugEnabled()) { 1562 TraceTm.recovery.debug("gettxxid= " + new String (mytxRecovered.gettxxid())); 1563 TraceTm.recovery.debug("stx=" + stx); 1564 } 1565 1566 if (new String (mytxRecovered.gettxxid()).equals(stx)) { 1567 mytxfound = true; 1568 break; 1569 } 1570 } 1571 1572 rmList = new Vector (); 1573 RecoverRmInfo rmInfo = null; 1574 vRecoverRmInfo = JotmRecovery.getRecoverRmInfo(); 1575 String myrm = null; 1576 Vector vRmRegistration = tr.getRmRegistration(); 1577 1578 if (mytxfound) { 1579 myxacount = mytxRecovered.getxidcount(); 1580 1581 if (TraceTm.recovery.isDebugEnabled()) { 1582 TraceTm.recovery.debug("myxacount= " + myxacount); 1583 } 1584 1585 for (int i=0; i<myxacount; i++) { 1586 myrmregistered = false; 1587 myrmifound = false; 1588 myxaresfound = false; 1589 mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(i); 1590 1591 if (mytxxidRecovered == null) { 1592 xaList.add("NotFound" + "????" + 1593 "NotFound" + "????" + 1594 "NotFound" + "????" + 1595 "NotFound" + "????" + 1596 "NotFound"); 1597 } else { 1598 rmiCount = vRecoverRmInfo.size(); 1599 1600 if (TraceTm.recovery.isDebugEnabled()) { 1601 TraceTm.recovery.debug("rmiCount= " + rmiCount); 1602 } 1603 1604 for (int j=0; j<rmiCount; j++){ 1605 rmInfo = (RecoverRmInfo) vRecoverRmInfo.elementAt(j); 1606 1607 if (TraceTm.recovery.isDebugEnabled()) { 1608 TraceTm.recovery.debug("getRecoverXaResName()= " + rmInfo.getRecoverXaResName()); 1609 TraceTm.recovery.debug("getRecoverxaresname()=" + mytxxidRecovered.getRecoverxaresname()); 1610 TraceTm.recovery.debug("getRecoverXaRes()= " + new String (rmInfo.getRecoverXaRes())); 1611 TraceTm.recovery.debug("getRecoverxares()=" + new String (mytxxidRecovered.getRecoverxares())); 1612 } 1613 1614 if ((new String (rmInfo.getRecoverXaRes())).equals(new String (mytxxidRecovered.getRecoverxares()))) { 1616 myrm = rmInfo.getRecoverRm(); 1617 myrmifound = true; 1618 myxares = new String (mytxxidRecovered.getRecoverxares()); 1619 1620 if (TraceTm.recovery.isDebugEnabled()) { 1621 TraceTm.recovery.debug("myrm= " + myrm); 1622 TraceTm.recovery.debug("myxares= " + myxares); 1623 } 1624 break; 1625 } 1626 } 1627 1628 if (!myrmifound) { 1629 myrm = "NotFound"; 1630 } 1631 1632 if (vRmRegistration == null) { 1633 if (TraceTm.recovery.isDebugEnabled()) { 1634 TraceTm.recovery.debug("vRmRegistration is null"); 1635 } 1636 myxares = "NotRegistered"; 1637 } else { 1638 int rmregcount = vRmRegistration.size(); 1639 1640 if (TraceTm.recovery.isDebugEnabled()) { 1641 TraceTm.recovery.debug("rmregcount= " + rmregcount); 1642 } 1643 1644 for (int j=0; j<rmregcount; j++){ 1645 myRmRegistration = (RmRegistration) vRmRegistration.elementAt(j); 1646 1647 if (TraceTm.recovery.isDebugEnabled()) { 1648 TraceTm.recovery.debug("myrm= " + myrm); 1649 TraceTm.recovery.debug("rmGetName= " + myRmRegistration.rmGetName()); 1650 } 1651 1652 if (myrm.equals(myRmRegistration.rmGetName())) { 1653 myrmregistered = true; 1654 1655 if (myRmRegistration.rmGetXaRes() == null) { 1656 myxares = "IsNull"; 1657 } else { 1658 myxares = myRmRegistration.rmGetXaRes().toString(); 1659 myxaresfound = true; 1660 1661 if (TraceTm.recovery.isDebugEnabled()) { 1662 TraceTm.recovery.debug("myxares= " + myxares); 1663 } 1664 } 1665 break; 1666 } 1667 } 1668 1669 if (!myrmregistered) { 1670 myxares = "NotRegistered"; 1671 } 1672 1673 if (TraceTm.recovery.isDebugEnabled()) { 1674 TraceTm.recovery.debug("myxares= " + myxares); 1675 } 1676 } 1677 1678 Xid tempxid = new XidImpl(mytxxidRecovered.getRecoverxid()); 1679 1680 xaList.add(myrm + "????" + 1684 myxares + "????" + 1685 new String (mytxxidRecovered.getRecoverxid()) + "????" + 1686 new String (tempxid.toString()) + "????" + 1687 StatusHelper.getStatusName (mytxxidRecovered.getRecoverstatus())); 1688 } 1689 } 1690 } 1691 1692 String [] myTxString = new String [myxacount] ; 1693 1694 for (int i=0; i < myxacount; i++) { 1695 myTxString[i] = xaList.get(i).toString(); 1696 } 1697 1698 return myTxString; 1699 } 1700 1701 1704 public int actionXAResource (String xaAction, String xatx) { 1705 int commiterror; 1706 1707 Vector vRmRegistration = null; 1708 Vector vRecoverRmInfo = null; 1709 int rmregcount; 1710 boolean mytxfound = false; 1711 boolean myrmifound = false; 1712 String mytxstatusname; 1713 JotmRecovery myjr = null; 1714 RmRegistration myRmRegistration = null; 1715 XAResource xaresource = null; 1716 1717 if (tr == null) { 1718 return 0; 1719 } 1720 1721 myjr = tr.getJotmRecovery(); 1722 1723 if (myjr == null) { 1724 return 0; 1725 } 1726 1727 vRmRegistration = tr.getRmRegistration(); 1728 1729 if (vRmRegistration == null) { 1730 return 0; 1731 } 1732 1733 1745 String mys = xatx; 1746 int myix1 = mys.indexOf('\n'); 1747 String sResmgr = mys.substring(0, myix1); 1748 int myix2 = mys.indexOf('\n', myix1 + 1); 1749 String sResource = mys.substring(myix1 + 1, myix2); 1750 int myix3 = mys.indexOf('\n', myix2 + 1); 1751 String sFullXid = mys.substring(myix2 + 1, myix3); 1752 String sXidstate = mys.substring(myix3 + 1); 1753 1754 rmregcount = vRmRegistration.size(); 1755 1756 for (int i=0; i<rmregcount; i++){ 1757 myRmRegistration = (RmRegistration) vRmRegistration.elementAt(i); 1758 1759 if (sResmgr.equals(myRmRegistration.rmGetName())) { 1760 xaresource = myRmRegistration.rmGetXaRes(); 1761 break; 1762 } 1763 } 1764 1765 int rcflag = 0; 1766 1767 javax.transaction.xa.Xid javaxid [] = new javax.transaction.xa.Xid [100]; 1768 1769 try { 1770 javaxid = xaresource.recover(rcflag); 1773 } catch (XAException e) { 1774 if (TraceTm.jta.isDebugEnabled()) { 1775 TraceTm.recovery.debug("xaResource.recover call failed during recovery " + e.getMessage()); 1776 } 1777 } 1778 1779 if (javaxid == null) { 1780 1781 if (TraceTm.recovery.isDebugEnabled()) { 1782 TraceTm.recovery.debug("No XIDs to recover for Xares javaxid is null"); 1783 } 1784 1785 cleanuptxrecovery(sFullXid); 1786 return 0; 1787 } 1788 1789 if (javaxid.length == 0) { 1790 1791 if (TraceTm.recovery.isDebugEnabled()) { 1792 TraceTm.recovery.debug("No XIDs to recover for Xares= "+ xaresource); 1793 } 1794 1795 cleanuptxrecovery(sFullXid); 1796 return 0; 1797 } 1798 1799 Xid rcxid [] = new Xid[javaxid.length]; 1800 1801 for (int xx=0; xx<javaxid.length; xx++) { 1802 1803 if (javaxid[xx] == null) break; 1804 1805 if (new String (javaxid[xx].toString()).equals(sFullXid)) { 1806 1807 if (xaAction == "commit") { 1808 try { 1809 xaresource.commit(javaxid[xx], false); 1810 } catch (XAException e) { 1811 TraceTm.recovery.error("Unable to commit Xid during Admin Recovery " + e.getMessage()); 1812 } 1813 } else { 1814 if (xaAction == "rollback") { 1815 try { 1816 xaresource.rollback(javaxid[xx]); 1817 } catch (XAException e) { 1818 TraceTm.recovery.error("Unable to rollback Xid during Admin Recovery " + e.getMessage()); 1819 } 1820 } else { 1821 if (xaAction == "forget") { 1822 try { 1823 xaresource.rollback(javaxid[xx]); 1824 } catch (XAException e) { 1825 TraceTm.recovery.error("Unable to rollback Xid during Admin Recovery " + e.getMessage()); 1826 } 1827 } 1828 } 1829 } 1830 } 1831 break; 1832 } 1833 1834 cleanuptxrecovery(sFullXid); 1835 return 0; 1836 } 1837 1838 private void cleanuptxrecovery(String pFullXid) { 1839 1840 1845 Vector vTxRecovered = null; 1846 TxRecovered mytxRecovered = null; 1847 TxxidRecovered mytxxidRecovered = null; 1848 int txCount; 1849 int myxacount = 0; 1850 boolean mytxxidrecoveredfound = false; 1851 1852 byte [] jotmDone = new byte [11]; 1853 byte [] [] jotmDoneRecord = new byte [1] [11]; 1854 1855 jotmDone = "RR3JOTMDONE".getBytes(); 1856 1857 vTxRecovered = JotmRecovery.getTxRecovered(); 1858 txCount = vTxRecovered.size(); 1859 1860 for (int i=0; i<txCount; i++){ 1861 mytxRecovered = (TxRecovered) vTxRecovered.elementAt(i); 1862 myxacount = mytxRecovered.getxidcount(); 1863 1864 for (int j=0; j<myxacount; j++) { 1865 mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(j); 1866 1867 if (mytxxidRecovered != null) { 1868 1869 if (pFullXid.equals(new String (mytxxidRecovered.getRecoverxid()))) { 1870 mytxxidRecovered.setRecoverstatus(Status.STATUS_COMMITTED); 1872 mytxxidrecoveredfound = true; 1873 break; 1874 } 1875 } 1876 } 1877 1878 boolean allcompleted = true; 1879 1880 for (int j=0; j<myxacount; j++) { 1881 mytxxidRecovered = mytxRecovered.getRecoverTxXidInfo(j); 1882 1883 if (mytxxidRecovered.getRecoverstatus() != Status.STATUS_COMMITTED) { allcompleted = false; 1886 break; 1887 } 1888 } 1889 1890 if (allcompleted) { 1891 XACommittingTx xaCommitTx = mytxRecovered.getXACommittingTx(); 1892 jotmDoneRecord [0] = jotmDone; 1893 1894 if (Current.getDefaultRecovery()) { 1895 try { 1896 if (TraceTm.recovery.isDebugEnabled()) { 1897 TraceTm.recovery.debug("Done howl log, after admin action"); 1898 } 1899 1900 TransactionRecoveryImpl.getTransactionRecovery().howlDoneLog(jotmDoneRecord, xaCommitTx); 1901 } catch (Exception f) { 1902 String howlerror = 1903 "Cannot howlDoneLog:" 1904 + f 1905 + "--" 1906 + f.getMessage(); 1907 TraceTm.jotm.error("Got LogException from howlDoneLog: "+ howlerror); 1908 } 1909 } 1910 1911 vTxRecovered.remove(i); 1912 break; 1913 } 1914 1915 if (mytxxidrecoveredfound) return; 1916 } 1917 } 1918 1919 1923 1924 public void associateThreadTx(Xid xid) { 1925 1926 TransactionImpl tx = getTxXid(xid); 1927 threadTx.set(tx); 1928 1929 if (TraceTm.jta.isDebugEnabled()) { 1930 TraceTm.jta.debug("threadTx.set= " + threadTx.toString()); 1931 } 1932 } 1933 1934 1938 public void clearThreadTx() { 1939 1940 TransactionImpl tx = (TransactionImpl) threadTx.get(); 1941 1942 if (tx != null) { 1943 threadTx.set(null); 1944 if (TraceTm.jta.isDebugEnabled()) { 1945 TraceTm.jta.debug("threadTx.set=null"); 1946 } 1947 } 1948 } 1949 1950 1954 1957 1958 private void putTxXid( Xid xid, TransactionImpl tx ) { 1959 1960 if ( TraceTm.jta.isDebugEnabled() ) { 1961 TraceTm.jta.debug("Associate tx to xid (xid=" + xid + ")"); 1962 } 1963 1964 txXids.put(xid, tx); 1965 } 1966 1967 1970 1971 private TransactionImpl getTxXid( Xid xid ) { 1972 1973 if ( TraceTm.jta.isDebugEnabled() ) { 1974 TraceTm.jta.debug("get tx from xid (xid="+ xid +")"); 1975 } 1976 1977 TransactionImpl tx = (TransactionImpl) txXids.get(xid); 1978 return tx; 1979 } 1980 1981 1984 1985 private void removeTxXid( Xid xid ) { 1986 1987 if ( TraceTm.jta.isDebugEnabled() ) { 1988 TraceTm.jta.debug("remove tx from xid (xid="+ xid +")"); 1989 } 1990 1991 txXids.remove (xid); 1992 } 1993 1994 1997 1998 void forget() throws Exception { 1999 threadTx.set(null); 2000 2001 if (TraceTm.jta.isDebugEnabled()) { 2002 TraceTm.jta.debug("threadTx.set= null"); 2003 } 2004 } 2005 2006 2007 2008 2013 2014 public int getTotalCurrentTransactions() { 2015 return txXids.size(); 2016 } 2017 2018 2021 2022 synchronized void incrementBeginCounter() { 2023 nb_bg_tx++; 2024 } 2025 2026 2031 2032 public int getTotalBegunTransactions() { 2033 return nb_bg_tx; 2034 } 2035 2036 2039 2040 synchronized void incrementRollbackCounter() { 2041 nb_rb_tx++; 2042 } 2043 2044 2049 2050 public int getTotalRolledbackTransactions() { 2051 return nb_rb_tx; 2052 } 2053 2054 2057 2058 synchronized void incrementCommitCounter() { 2059 nb_cm_tx++; 2060 } 2061 2062 2067 2068 public int getTotalCommittedTransactions() { 2069 return nb_cm_tx; 2070 } 2071 2072 2075 2076 public synchronized void resetAllTxTotalCounters() { 2077 nb_bg_tx = 0; 2078 nb_cm_tx = 0; 2079 nb_rb_tx = 0; 2080 nb_to = 0; 2081 } 2082 2083 2086 2087 synchronized void incrementExpiredCounter() { 2088 nb_to++; 2089 } 2090 2091 2096 2097 public int getTotalExpiredTransactions() { 2098 return nb_to; 2099 } 2100 2101 2107 2108 public synchronized Integer [] getTransactionCounters() { 2109 Integer [] result = new Integer [5]; 2110 result[0] = new Integer (txXids.size()); 2111 result[1] = new Integer (nb_bg_tx); 2112 result[2] = new Integer (nb_cm_tx); 2113 result[3] = new Integer (nb_rb_tx); 2114 result[4] = new Integer (nb_to); 2115 return result; 2116 } 2117 2118} 2119 | Popular Tags |