1 23 24 28 29 51 package com.sun.jts.CosTransactions; 52 53 import java.util.*; 54 import java.io.*; 55 56 import org.omg.CORBA.*; 57 import org.omg.CosTransactions.*; 58 59 import com.sun.jts.jtsxa.*; 60 61 import javax.transaction.xa.*; 62 import com.sun.jts.jta.TransactionManagerImpl; 63 64 import com.sun.jts.trace.*; 65 import java.util.logging.Logger ; 66 import java.util.logging.Level ; 67 import com.sun.logging.LogDomains; 68 import com.sun.jts.utils.LogFormatter; 69 import com.sun.enterprise.autotxrecovery.TransactionRecovery; 70 80 81 88 public class RecoveryManager { 89 90 93 private static Enumeration uniqueRMSet = null; 94 95 98 private static boolean initialised = false; 99 100 105 private static int resyncCoords = 0; 106 107 111 private static ResyncThread resyncThread = null; 112 113 117 private static EventSemaphore resyncInProgress = new EventSemaphore(); 118 119 123 private static EventSemaphore recoveryInProgress = new EventSemaphore(); 124 125 129 private static EventSemaphore uniqueRMSetReady = new EventSemaphore(); 130 131 private static Hashtable coordsByGlobalTID = new Hashtable(); 132 private static Hashtable coordsByLocalTID = new Hashtable(); 133 134 138 private static Hashtable transactionIds = new Hashtable(); 139 140 143 private static Hashtable inCompleteTxMap = new Hashtable(); 144 145 private static TransactionRecovery txRecovery; 147 148 149 150 153 private static java.lang.Object lockObject = new java.lang.Object (); 154 157 static Logger _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER); 158 167 static void initialise() { 168 169 171 if (initialised) { 172 return; 173 } 174 175 initialised = true; 176 177 179 if (Configuration.isRecoverable()) { 180 resyncThread = new ResyncThread(); 181 if(_logger.isLoggable(Level.FINE)) 182 { 183 _logger.logp(Level.FINE,"RecoveryManager","initialise()", 184 "Before starting ResyncThread "); 185 } 186 resyncThread.start(); 187 } else { 188 189 193 if (!Configuration.isAppClientContainer()) { 194 String serverName = Configuration.getServerName(); 195 if (serverName != null && Log.checkFileExists(serverName)) { 196 _logger.log(Level.INFO,"jts.log_file_transient_server",serverName); 197 198 } 199 } 200 201 205 try { 206 recoveryInProgress.post(); resyncComplete(false, false); 208 } catch (Throwable exc) {} 209 } 210 } 211 212 233 static boolean addCoordinator(GlobalTID globalTID, 234 Long localTID, CoordinatorImpl coord, int timeout) { 235 236 boolean result = true; 237 238 241 coordsByGlobalTID.put(globalTID,coord); 242 coordsByLocalTID.put(localTID,coord); 243 244 249 if (timeout != 0) { 250 TimeoutManager.setTimeout(localTID, TimeoutManager.ACTIVE_TIMEOUT, 251 timeout); 252 } 253 254 return result; 255 } 256 257 274 static boolean removeCoordinator(GlobalTID globalTID, 275 Long localTID, boolean aborted) { 276 277 boolean result = false; 278 279 281 CoordinatorImpl coord = null; 282 result = (coordsByGlobalTID.remove(globalTID) != null); 283 284 286 if (result) { 287 coord = (CoordinatorImpl) coordsByLocalTID.remove(localTID); 288 result = (coord != null); 289 } 290 291 296 if (coord != null) { 297 try { 298 if (coord.is_top_level_transaction()) { 299 if (Configuration.isDBLoggingEnabled()) 300 LogDBHelper.getInstance().deleteRecord(localTID.longValue()); 301 else 302 CoordinatorLog.removeLog(localTID); 303 } 304 } catch(SystemException exc) { 305 result = false; 306 } 307 } 308 309 312 TimeoutManager.setTimeout(localTID, TimeoutManager.CANCEL_TIMEOUT, 0); 313 314 317 318 319 325 328 if (resyncCoords > 0) { 329 330 resyncCoords--; 331 332 335 if (resyncCoords == 0) { 336 try { 337 resyncComplete(true, true); 338 } catch (Throwable exc) {} 339 } 340 } 341 342 return result; 343 } 344 345 355 static CoordinatorImpl getCoordinator(GlobalTID globalTID) { 356 357 CoordinatorImpl result = (CoordinatorImpl) 358 coordsByGlobalTID.get(globalTID); 359 360 return result; 361 } 362 363 373 static boolean readAndUpdateTxMap(GlobalTID tid) { 374 synchronized (transactionIds) { 375 Thread thread = (Thread ) transactionIds.get(tid); 376 if (thread != null) { return false; 378 } 379 transactionIds.put(tid, Thread.currentThread()); 381 return true; 382 } 383 } 384 385 392 static Thread getThreadFromTxMap(GlobalTID tid) { 393 return (Thread ) transactionIds.get(tid); 394 } 395 396 402 static Thread removeFromTxMap(GlobalTID tid) { 403 return (Thread ) transactionIds.remove(tid); 404 } 405 406 421 static boolean recover() { 422 423 boolean result = false; 424 425 429 boolean keypointRequired = false; 430 Enumeration logRecords = CoordinatorLog.getLogged(); 431 432 while (logRecords.hasMoreElements()) { 433 keypointRequired = true; 434 try { 435 new TopCoordinator(). 436 reconstruct((CoordinatorLog) logRecords.nextElement()); 437 } catch(Exception exc) { 438 _logger.log(Level.SEVERE,"jts.recovery_in_doubt_exception",exc); 439 _logger.log(Level.SEVERE,"jts.recovery_in_doubt",exc.toString()); 440 String msg = LogFormatter.getLocalizedMessage(_logger, 441 "jts.recovery_in_doubt", 442 new java.lang.Object [] {exc.toString()}); 443 throw new org.omg.CORBA.INTERNAL (msg); 444 } 445 } 446 447 449 if(_logger.isLoggable(Level.FINE)) 451 { 452 _logger.logp(Level.FINE,"RecoveryManager","recover()", 453 "Before invoking proceedWithXARecovery()"); 454 } 455 proceedWithXARecovery(); 456 457 460 recoveryInProgress.post(); 461 462 465 result = coordsByGlobalTID.size() > 0; 466 if (!result) { 467 try { 468 resyncComplete(false,keypointRequired); 469 } catch(Throwable exc) {} 470 } 471 472 return result; 473 } 474 475 490 static void resync() { 491 492 498 505 resyncCoords = coordsByGlobalTID.size(); 506 Enumeration resyncList = 507 ((Hashtable) coordsByGlobalTID.clone()).elements(); 508 509 boolean isRoot[] = new boolean[1]; 510 511 514 while (resyncList.hasMoreElements()) { 515 516 TopCoordinator coord = (TopCoordinator)resyncList.nextElement(); 517 518 try { 519 520 522 synchronized (coord) { 523 524 Status state = coord.recover(isRoot); 525 526 if (state == Status.StatusUnknown) { 527 528 539 TimeoutManager.setTimeout( 540 new Long (coord.getLocalTID()), 541 TimeoutManager.IN_DOUBT_TIMEOUT, 542 60); 543 544 } else if (state == Status.StatusCommitted) { 545 546 if(_logger.isLoggable(Level.FINE)) 554 { 555 _logger.logp(Level.FINE,"RecoveryManager","resync()", 556 "Before invoking commit on the reconstructed coordinator"+ 557 "GTID is: "+ 558 ((TopCoordinator)coord).superInfo.globalTID.toString()); 559 560 } 561 562 563 try { 564 coord.commit(); 565 } catch (Throwable exc) { 566 _logger.log(Level.WARNING,"jts.exception_during_resync", 567 new java.lang.Object [] {exc.toString(),"commit"}); 568 } 569 570 if (isRoot[0]) { 571 try { 572 coord.afterCompletion(state); 573 } catch (Throwable exc) { 574 _logger.log(Level.WARNING,"jts.exception_during_resync", 575 new java.lang.Object [] {exc.toString(), 576 "after_completion"}); 577 } 578 } 579 580 } else { 581 582 584 try { 585 if(_logger.isLoggable(Level.FINE)) 586 { 587 _logger.logp(Level.FINE,"RecoveryManager","resync()", 588 "Before invoking rollback on the"+ 589 "reconstructed coordinator :"+ 590 "GTID is : "+ 591 ((TopCoordinator)coord).superInfo.globalTID.toString()); 592 593 } 594 coord.rollback(true); 595 } catch (Throwable exc) { 596 _logger.log(Level.WARNING,"jts.resync_failed", 597 new java.lang.Object [] {exc.toString(),"rollback"}); 598 } 599 600 if (isRoot[0]) { 601 try { 602 coord.afterCompletion(Status.StatusRolledBack); 603 } catch (Throwable exc) { 604 _logger.log(Level.WARNING,"jts.resync_failed", 605 new java.lang.Object [] 606 { exc.toString(), "after_completion"}); 607 } 608 } 609 } 610 } 611 } catch (Throwable exc) {} 612 } 613 614 } 618 619 637 static void resyncComplete(boolean resynced, 638 boolean keypointRequired) throws LogicErrorException { 639 640 643 646 648 if (keypointRequired) { 649 CoordinatorLog.keypoint(); 650 } 651 652 654 resyncInProgress.post(); 655 resyncInProgress = null; 656 } 657 658 668 static CoordinatorImpl getLocalCoordinator(Long localTID) { 669 670 CoordinatorImpl result = (CoordinatorImpl) 671 coordsByLocalTID.get(localTID); 672 673 return result; 674 } 675 676 686 static boolean validLocalTID(Long localTID) { 687 688 boolean result = coordsByLocalTID.containsKey(localTID); 689 690 return result; 691 } 692 693 707 static void shutdown(boolean immediate) { 708 709 710 720 721 723 if (resyncInProgress != null) { 724 try { 725 resyncInProgress.waitEvent(); 726 if (resyncThread != null) { 727 resyncThread.join(); 728 } 729 } catch (InterruptedException exc) {} 730 } 731 734 735 738 741 if (!immediate && Configuration.isRecoverable()) { 742 CoordinatorLog.keypoint(); 743 CoordinatorLog.finalizeAll(); 744 } 745 746 } 748 749 754 private static String stringifyXid(Xid xid) { 755 int glen = xid.getGlobalTransactionId().length; 756 int blen = xid.getBranchQualifier().length; 757 byte[] xidRep = new byte[glen + 1 + blen]; 758 759 System.arraycopy(xid.getGlobalTransactionId(), 0, xidRep, 0, glen); 760 xidRep[glen] = (byte) ','; 761 System.arraycopy(xid.getBranchQualifier(), 0, xidRep, glen + 1, blen); 762 763 return new String (xidRep); 764 } 765 766 770 private static Enumeration getUniqueRMSet(Enumeration xaResourceList){ 771 772 Vector uniqueRMList = new Vector(); 773 774 while (xaResourceList.hasMoreElements()) { 775 XAResource xaRes = (XAResource) xaResourceList.nextElement(); 776 int size = uniqueRMList.size(); 777 boolean match = false; 778 for (int i = 0; i < size; i++) { XAResource uniqueXaRes = (XAResource) uniqueRMList.elementAt(i); 780 try { 781 if (xaRes.isSameRM(uniqueXaRes)) { 782 match = true; 783 break; 784 } 785 } catch (XAException xe) {} 786 } 787 if (!match) { 788 uniqueRMList.add(xaRes); 789 } 790 } 791 792 return uniqueRMList.elements(); 793 } 794 795 804 public static void recoverXAResources(Enumeration xaResources) { 805 806 807 808 String manualRecovery = 809 Configuration.getPropertyValue(Configuration.MANUAL_RECOVERY); 810 811 if (manualRecovery == null || 813 !(manualRecovery.equalsIgnoreCase("true"))) { 814 return; 815 } 816 817 synchronized (lockObject) { 818 819 if (uniqueRMSetReady.isPosted() == false) { 820 RecoveryManager.uniqueRMSet = getUniqueRMSet(xaResources); 821 uniqueRMSetReady.post(); 822 waitForResync(); 823 return; 824 } else { 825 RecoveryManager.waitForResync(); 826 RecoveryManager.uniqueRMSet = getUniqueRMSet(xaResources); 827 proceedWithXARecovery(); 834 } 835 } 836 } 837 838 841 842 static Xid[] getInDoubtXids(XAResource xaResource) { 843 if(_logger.isLoggable(Level.FINE)) 844 { 845 _logger.logp(Level.FINE,"RecoveryManager", "getInDoubtXids()", 846 "Before receiving inDoubtXids from xaresource = " + 847 xaResource); 848 } 849 Xid[] inDoubtXids = null; 850 ArrayList inDoubtXidList = null; 851 int flags; 852 String recoveryScanFlags = System.getProperty("RECOVERSCANFLAGS"); 853 if (recoveryScanFlags != null && recoveryScanFlags.equals("TMNOFLAGS")) 854 flags = XAResource.TMSTARTRSCAN; 855 else 856 flags = XAResource.TMSTARTRSCAN | XAResource.TMENDRSCAN; 857 boolean continueLoop = true; 858 while (continueLoop) { 859 try { 860 inDoubtXids = xaResource.recover(flags); 861 if (inDoubtXids == null || inDoubtXids.length == 0) 862 break; 863 if (flags == XAResource.TMSTARTRSCAN || flags == XAResource.TMNOFLAGS) { 864 flags = XAResource.TMNOFLAGS; 865 if (inDoubtXidList == null) { 866 inDoubtXidList = new ArrayList(); 867 } 868 for (int i = 0; i < inDoubtXids.length; i++) 869 inDoubtXidList.add(inDoubtXids[i]); 870 } 871 else { 872 break; 873 } 874 } catch (XAException e) { 875 _logger.log(Level.WARNING,"jts.xaexception_in_recovery",e); 876 break; 877 } 878 879 } 880 if (inDoubtXidList != null) 881 inDoubtXids = (Xid[])inDoubtXidList.toArray(); 882 if(_logger.isLoggable(Level.FINE) && (inDoubtXids != null)) 883 { 884 String xidList = LogFormatter.convertXidArrayToString(inDoubtXids); 885 _logger.logp(Level.FINE,"RecoveryManager", 886 "getInDoubtXid()", 887 "InDoubtXids returned from xaresource = "+ 888 xaResource + "are: " +xidList); 889 } 890 return inDoubtXids; 891 } 892 893 900 private static void proceedWithXARecovery() { 901 902 903 904 Enumeration xaResources = RecoveryManager.uniqueRMSet; 905 String manualRecovery = 906 Configuration.getPropertyValue(Configuration.MANUAL_RECOVERY); 907 908 if (manualRecovery == null || 910 !(manualRecovery.equalsIgnoreCase("true"))) { 911 return; 912 } 913 914 if (Thread.currentThread().getName().equals("JTS Resync Thread")) { 915 916 if (uniqueRMSetReady != null) { 917 try { 918 uniqueRMSetReady.waitEvent(); 919 txRecovery.start(); 920 txRecovery.raiseFence(); 921 xaResources = RecoveryManager.uniqueRMSet; 922 } catch (InterruptedException exc) { 923 _logger.log(Level.SEVERE,"jts.wait_for_resync_complete_interrupted"); 924 String msg = LogFormatter.getLocalizedMessage(_logger, 925 "jts.wait_for_resync_complete_interrupted"); 926 throw new org.omg.CORBA.INTERNAL (msg); 927 } 928 } 929 } 930 931 if (xaResources == null) { 933 return; 934 } 935 936 Vector otsResources = new Vector(); 937 Map uniqueXids = new Hashtable(); 938 939 while (xaResources.hasMoreElements()) { 940 941 XAResource xaResource = (XAResource) xaResources.nextElement(); 942 943 946 Xid[] inDoubtXids = getInDoubtXids(xaResource); 947 uniqueXids.clear(); 948 if (inDoubtXids == null || inDoubtXids.length == 0) { 949 continue; } 951 952 for (int i = 0; i < inDoubtXids.length; i++) { 953 954 956 String branchQualifier = 957 new String (inDoubtXids[i].getBranchQualifier()); 958 String serverName = Configuration.getServerName(); 959 960 if (branchQualifier.startsWith(serverName)) { 961 962 970 String xidStr = stringifyXid(inDoubtXids[i]); 971 if (uniqueXids.get(xidStr) == null) { 973 uniqueXids.put(xidStr, xidStr); 975 otsResources.addElement( 979 new OTSResourceImpl(inDoubtXids[i], 980 xaResource, null 981 ).getCORBAObjReference()); 982 } 983 } 984 } 985 } 986 987 988 991 for (int i = 0; i < otsResources.size(); i++) { 992 993 OTSResource otsResource = (OTSResource) otsResources.elementAt(i); 994 GlobalTID globalTID = new GlobalTID(otsResource.getGlobalTID()); 995 TopCoordinator coord = 996 (TopCoordinator) coordsByGlobalTID.get(globalTID); 997 998 if (coord == null) { 999 if(_logger.isLoggable(Level.FINE)) 1003 { 1004 _logger.logp(Level.FINE,"RecoveryManager","proceedWithXARecovery()", 1005 "Could not recognize OTSResource: "+otsResource + 1006 " with tid: " + 1007 LogFormatter.convertToString(globalTID.realTID.tid)+ 1008 ";Hence rolling this resource back..."); 1009 } 1010 1011 boolean infiniteRetry = true; 1012 int commitRetries = Configuration.getRetries(); 1013 if (commitRetries >= 0) 1014 infiniteRetry = false; 1015 int commitRetriesLeft = commitRetries; 1016 boolean exceptionisThrown = true; 1017 while (exceptionisThrown) { 1018 try { 1019 otsResource.rollback(); 1020 exceptionisThrown = false; 1021 } catch (Throwable exc) { 1022 if ((exc instanceof COMM_FAILURE) || (exc instanceof TRANSIENT)) { 1023 if (commitRetriesLeft > 0 || infiniteRetry) { 1024 if (!infiniteRetry) { 1027 commitRetriesLeft--; 1028 } 1029 1030 try { 1031 Thread.sleep(Configuration.COMMIT_RETRY_WAIT); 1032 } catch( Throwable e ) {} 1033 } 1034 else { 1035 _logger.log(Level.WARNING,"jts.exception_during_resync", 1036 new java.lang.Object [] {exc.toString(),"OTSResource rollback"}); 1037 exceptionisThrown = false; 1038 } 1039 } 1040 else { 1041 _logger.log(Level.WARNING,"jts.exception_during_resync", 1042 new java.lang.Object [] {exc.toString(),"OTSResource rollback"}); 1043 exceptionisThrown = false; 1044 } 1045 } 1046 } 1047 } else { 1048 1057 if(_logger.isLoggable(Level.FINE)) 1060 { 1061 _logger.logp(Level.FINE,"RecoveryManager", 1062 "proceedWithXARecovery()", 1063 "Recognized OTSResource: " + otsResource + 1064 " with tid: " + 1065 LogFormatter.convertToString(globalTID.realTID.tid) + 1066 ";Hence registering this resource with coordinator..."); 1067 } 1068 coord.directRegisterResource(otsResource); 1069 } 1070 } 1071 } 1072 1073 static void dbXARecovery() { 1074 Enumeration xaResources = RecoveryManager.uniqueRMSet; 1075 String manualRecovery = 1076 Configuration.getPropertyValue(Configuration.MANUAL_RECOVERY); 1077 if (manualRecovery == null || 1079 !(manualRecovery.equalsIgnoreCase("true"))) { 1080 try { 1081 resyncComplete(false, false); 1082 } catch (Throwable ex) { } 1083 return; 1084 } 1085 1086 if (Thread.currentThread().getName().equals("JTS Resync Thread")) { 1087 if (uniqueRMSetReady != null) { 1088 try { 1089 uniqueRMSetReady.waitEvent(); 1090 xaResources = RecoveryManager.uniqueRMSet; 1091 } catch (InterruptedException exc) { 1092 _logger.log(Level.SEVERE,"jts.wait_for_resync_complete_interrupted"); 1093 String msg = LogFormatter.getLocalizedMessage(_logger, 1094 "jts.wait_for_resync_complete_interrupted"); 1095 throw new org.omg.CORBA.INTERNAL (msg); 1096 } 1097 } 1098 } 1099 1100 if (xaResources == null) { 1102 try { 1103 resyncComplete(false, false); 1104 } catch (Throwable ex) { } 1105 return; 1106 } 1107 1108 Map gtidMap = LogDBHelper.getInstance().getGlobalTIDMap(); 1110 1111 Map uniqueXids = new Hashtable(); 1112 1113 while (xaResources.hasMoreElements()) { 1114 1115 XAResource xaResource = (XAResource) xaResources.nextElement(); 1116 1117 1120 Xid[] inDoubtXids = getInDoubtXids(xaResource); 1121 uniqueXids.clear(); 1122 if (inDoubtXids == null || inDoubtXids.length == 0) { 1123 continue; } 1125 for (int i = 0; i < inDoubtXids.length; i++) { 1126 1127 1129 String branchQualifier = 1130 new String (inDoubtXids[i].getBranchQualifier()); 1131 String serverName = Configuration.getServerName(); 1132 1133 if (branchQualifier.startsWith(serverName)) { 1134 1135 1143 String xidStr = stringifyXid(inDoubtXids[i]); 1144 if (uniqueXids.get(xidStr) == null) { 1146 uniqueXids.put(xidStr, xidStr); 1148 try { 1149 byte[] gtrid = inDoubtXids[i].getGlobalTransactionId(); 1150 GlobalTID gtid = GlobalTID.fromTIDBytes(gtrid); 1151 Long localTID = (Long )gtidMap.get(gtid); 1152 if (localTID == null) { 1153 xaResource.rollback(inDoubtXids[i]); 1154 } else { 1155 xaResource.commit(inDoubtXids[i], true); 1156 } 1157 LogDBHelper.getInstance().deleteRecord(localTID.longValue()); 1158 } catch (Exception ex) { ex.printStackTrace(); } 1159 } 1160 } 1161 } 1162 } 1163 try { 1164 resyncComplete(false, false); 1165 } catch (Throwable ex) { ex.printStackTrace(); } 1166 } 1167 1168 1169 1193 1197 1243 1244 1253 static CoordinatorImpl[] getCoordinators() { 1254 1255 int size = coordsByGlobalTID.size(); 1256 CoordinatorImpl[] result = new CoordinatorImpl[size]; 1257 1258 Enumeration coords = coordsByGlobalTID.elements(); 1259 1260 for(int pos = 0;pos<size;){ 1261 result[pos++] = (CoordinatorImpl) coords.nextElement(); 1262 } 1263 1264 return result; 1265 } 1266 1267 static Hashtable getCoordsByGlobalTID() 1268 { 1269 return coordsByGlobalTID; 1270 } 1271 1272 1273 1274 1283 public static byte[] getRestart() { 1284 1285 byte[] result = null; 1286 LogFile logFile = Configuration.getLogFile(); 1287 if (logFile != null) 1288 result = logFile.readRestart(); 1289 1290 return result; 1291 } 1292 1293 1302 public static void setRestart(byte[] bytes) { 1303 1304 LogFile logFile = Configuration.getLogFile(); 1305 1306 if (logFile != null) { 1307 if (!logFile.writeRestart(bytes)) { 1308 _logger.log(Level.WARNING,"jts.restart_write_failed"); 1309 } 1310 } 1311 } 1312 1313 1322 public static void waitForRecovery() { 1323 1324 if (recoveryInProgress != null) { 1325 try { 1326 recoveryInProgress.waitEvent(); 1327 } catch (InterruptedException exc) { 1328 _logger.log(Level.SEVERE,"jts.wait_for_resync_complete_interrupted"); 1329 String msg = LogFormatter.getLocalizedMessage(_logger, 1330 "jts.wait_for_resync_complete_interrupted"); 1331 throw new org.omg.CORBA.INTERNAL (msg); 1332 } 1333 } 1334 } 1335 1336 1345 public static void waitForResync() { 1346 1347 if (resyncInProgress != null) { 1348 try { 1349 resyncInProgress.waitEvent(); 1350 } catch (InterruptedException exc) { 1351 _logger.log(Level.SEVERE,"jts.wait_for_resync_complete_interrupted"); 1352 String msg = LogFormatter.getLocalizedMessage(_logger, 1353 "jts.wait_for_resync_complete_interrupted"); 1354 throw new org.omg.CORBA.INTERNAL (msg); 1355 } 1356 } 1357 } 1358 static void addToIncompleTx(CoordinatorImpl coord, boolean commit) { 1359 inCompleteTxMap.put(coord, new Boolean (commit)); 1360 } 1361 1362 public static void recoverIncompleteTx(XAResource[] xaresArray) { 1363 if ((xaresArray == null) || (xaresArray.length == 0)) 1364 return; 1365 int size = xaresArray.length; 1366 Vector v = new Vector(); 1367 for (int i=0; i<size; i++) { 1368 v.addElement(xaresArray[i]); 1369 } 1370 Enumeration resourceList = getUniqueRMSet(v.elements()); 1371 Map uniqueXids = new Hashtable(); 1372 Vector otsResources = new Vector(); 1373 while (resourceList.hasMoreElements()) { 1374 XAResource xaResource = (XAResource) resourceList.nextElement(); 1375 Xid[] inDoubtXids = getInDoubtXids(xaResource); 1378 uniqueXids.clear(); 1379 if (inDoubtXids == null || inDoubtXids.length == 0) { 1380 continue; } 1382 1383 for (int i = 0; i < inDoubtXids.length; i++) { 1384 1385 1387 String branchQualifier = 1388 new String (inDoubtXids[i].getBranchQualifier()); 1389 String serverName = Configuration.getServerName(); 1390 1391 if (branchQualifier.startsWith(serverName)) { 1392 1393 1401 String xidStr = stringifyXid(inDoubtXids[i]); 1402 if (uniqueXids.get(xidStr) == null) { uniqueXids.put(xidStr, xidStr); otsResources.addElement( 1405 new OTSResourceImpl(inDoubtXids[i], 1406 xaResource, null 1407 ).getCORBAObjReference()); 1408 } 1409 } 1410 } 1411 } for (int i = 0; i < otsResources.size(); i++) { 1413 OTSResource otsResource = (OTSResource) otsResources.elementAt(i); 1414 GlobalTID globalTID = new GlobalTID(otsResource.getGlobalTID()); 1415 synchronized (inCompleteTxMap) { 1416 Enumeration e = inCompleteTxMap.keys(); 1417 while (e.hasMoreElements()) { 1418 CoordinatorImpl cImpl = (CoordinatorImpl)e.nextElement(); 1419 GlobalTID gTID = new GlobalTID(cImpl.getGlobalTID()); 1420 if (gTID.equals(globalTID)) { 1421 Boolean commit = (Boolean ) inCompleteTxMap.get(cImpl); 1422 boolean infiniteRetry = true; 1423 int commitRetries = Configuration.getRetries(); 1424 if (commitRetries >= 0) 1425 infiniteRetry = false; 1426 int commitRetriesLeft = commitRetries; 1427 boolean exceptionisThrown = true; 1428 while (exceptionisThrown) { 1429 try { 1430 if (commit.booleanValue()) { 1431 otsResource.commit(); 1432 } 1433 else 1434 otsResource.rollback(); 1435 exceptionisThrown = false; 1436 } catch (Throwable exc) { 1437 if ((exc instanceof COMM_FAILURE) || (exc instanceof TRANSIENT)) { 1438 if (commitRetriesLeft > 0 || infiniteRetry) { 1439 if (!infiniteRetry) { 1442 commitRetriesLeft--; 1443 } 1444 try { 1445 Thread.sleep(Configuration.COMMIT_RETRY_WAIT); 1446 } catch( Throwable iex ) {} 1447 } 1448 else { 1449 _logger.log(Level.WARNING,"jts.exception_during_resync", 1450 new java.lang.Object [] {exc.toString(),"OTSResource rollback"}); 1451 exceptionisThrown = false; 1452 } 1453 } 1454 else { 1455 _logger.log(Level.WARNING,"jts.exception_during_resync", 1456 new java.lang.Object [] {exc.toString(),"OTSResource rollback"}); 1457 exceptionisThrown = false; 1458 } 1459 } 1460 } 1461 } 1462 } 1463 } 1464 } 1465 } 1466 1467 static void createRecoveryFile(String serverName) { 1468 try { 1469 int[] result = new int[1]; 1470 String logPath = Configuration.getDirectory(Configuration.LOG_DIRECTORY, 1471 Configuration.JTS_SUBDIRECTORY, 1472 result); 1473 if( result[0] == Configuration.DEFAULT_USED || 1474 result[0] == Configuration.DEFAULT_INVALID ) { 1475 if( result[0] == Configuration.DEFAULT_INVALID ) { 1476 logPath = "."; 1477 } 1478 } 1479 File recoveryFile = LogControl.recoveryIdentifierFile(serverName,logPath); 1480 RandomAccessFile raf = new RandomAccessFile(recoveryFile,"rw"); 1481 raf.writeBytes(serverName); 1482 raf.setLength(serverName.length()); 1483 raf.close(); 1484 } catch (Exception ex) { 1485 _logger.log(Level.WARNING,"jts.exception_in_recovery_file_handling",ex); 1486 } 1487 } 1488 1489 1493 1494 public static void registerTransactionRecoveryService(TransactionRecovery txRecoveryService) { 1495 txRecovery = txRecoveryService; 1496 } 1497 1498 1501 static TransactionRecovery getTransactionRecovery() { 1502 return txRecovery; 1503 } 1504 1505 1506 1516 1575} 1576 1577 1587 1588 1595class ResyncThread extends Thread { 1596 1597 1606 static Logger _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER); 1607 1608 ResyncThread() { 1609 setName("JTS Resync Thread"); 1610 setDaemon(true); 1611 } 1612 1613 1622 public void run() { 1623 yield(); 1624 1625 if(_logger.isLoggable(Level.FINE)) 1626 { 1627 _logger.logp(Level.FINE,"ResyncThread","run()","Before invoking RecoveryManager.recover()"); 1628 } 1629 try { 1630 if (Configuration.isDBLoggingEnabled()) { 1631 RecoveryManager.dbXARecovery(); 1632 } else { 1633 if (RecoveryManager.recover()) { 1634 RecoveryManager.resync(); 1635 } 1636 } 1637 } catch (Exception ex) { 1638 try { 1639 RecoveryManager.resyncComplete(false,false); 1640 } catch (Throwable tex) {tex.printStackTrace();} _logger.log(Level.SEVERE,"jts.log_exception_at_recovery",ex); 1642 } 1643 if(RecoveryManager.getTransactionRecovery() != null) 1644 RecoveryManager.getTransactionRecovery().lowerFence(); 1645 } 1646} 1647 | Popular Tags |