1 23 24 28 29 51 package com.sun.jts.CosTransactions; 52 53 import java.io.*; 54 import java.util.*; 55 import com.sun.jts.trace.*; 56 import org.omg.CosTransactions.*; 57 58 import com.sun.jts.utils.RecoveryHooks.FailureInducer; 59 60 import java.util.logging.Logger ; 61 import java.util.logging.Level ; 62 import com.sun.logging.LogDomains; 63 import com.sun.jts.utils.LogFormatter; 64 76 77 91 class TransactionState { 92 93 96 final static int STATE_NONE = 0; 97 98 102 final static int STATE_ACTIVE = 1; 103 104 108 final static int STATE_PREPARING = 2; 109 110 114 final static int STATE_PREPARED_SUCCESS = 3; 115 116 120 final static int STATE_PREPARED_FAIL = 4; 121 122 126 final static int STATE_PREPARED_READONLY = 5; 127 128 132 final static int STATE_COMMITTING = 6; 133 134 137 final static int STATE_COMMITTED = 7; 138 139 143 final static int STATE_ROLLING_BACK = 8; 144 145 148 final static int STATE_ROLLED_BACK = 9; 149 150 155 final static int STATE_COMMITTING_ONE_PHASE = 10; 156 157 158 162 final static int STATE_COMMITTED_ONE_PHASE_OK = 11; 163 164 165 169 final static int STATE_COMMIT_ONE_PHASE_ROLLED_BACK = 12; 170 171 175 final static int STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD = 13; 176 177 181 final static int STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED = 14; 182 183 186 static Logger _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER); 187 188 static RWLock freezeLock = new RWLock(); 189 GlobalTID globalTID = null; 190 Long localTID = null; 191 int state = STATE_NONE; 192 193 boolean subordinate = false; 194 CoordinatorLog logRecord = null; 195 Object logSection = null; 196 197 static long sequenceNumber = 1; 199 200 static boolean inDoubt = false; 201 202 205 static byte [] TIDTemplate=null; 207 208 215 216 final static boolean[][] validStateChange = { 219 220 { false, true, false, false, false, false, false, false, true, false, false, false, false, false, false }, 221 { false, false, true, false, false, false, false, false, true, false, true, false, false, false, false }, 222 { false, false, false, true, true, true, false, false, true, true, false, false, false, false, false }, 223 { false, false, false, false, false, false, true, false, true, false, false, false, false, false, false }, 224 { false, false, false, false, false, false, false, false, true, false, false, false, false, false, false }, 225 { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false }, 226 { false, false, false, false, false, false, true, true, false, false, false, false, false, false, false }, 227 { true, false, false, false, false, false, false, false, false, false, false, false, false, false, false }, 228 { false, false, false, false, false, false, false, false, true, true, false, false, false, false, false }, 229 { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false }, 230 { false, false, false, false , false, false, false, false, true, false, true, true, true, true, true }, 232 { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false }, 233 { false, false, false, false, false, false, false, false, false, true, false, false, false, false, false }, 234 { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false }, 235 { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false }}; 236 237 239 final static int XID_FORMAT_ID = ('J'<<16) + ('T'<<8) + 'S'; 240 241 private final static String LOG_SECTION_NAME = "TS"; 242 243 252 TransactionState() {} 253 254 271 TransactionState(CoordinatorLog log) { 272 273 275 localTID = new Long (getSequenceNumber()); 276 277 279 281 283 globalTID = new GlobalTID(XID_FORMAT_ID, 0, 284 generateTID(localTID.longValue())); 285 286 289 state = STATE_NONE; 290 subordinate = false; 291 292 294 if (log != null) { 295 logRecord = log; 296 logRecord.setLocalTID(localTID); 297 298 300 logSection = logRecord.createSection(LOG_SECTION_NAME); 301 } 302 } 303 304 320 TransactionState(GlobalTID globalTID, CoordinatorLog log) { 321 322 324 this.globalTID = globalTID; 325 localTID = new Long (getSequenceNumber()); 326 327 329 state = STATE_NONE; 330 subordinate = true; 331 332 334 if (log != null) { 335 logRecord = log; 336 337 339 logRecord.setLocalTID(localTID); 340 341 343 logSection = logRecord.createSection(LOG_SECTION_NAME); 344 } 345 } 346 347 362 TransactionState(Long parentLocalTID, GlobalTID parentGlobalTID) { 363 364 366 localTID = new Long (getSequenceNumber()); 367 368 370 372 374 globalTID = new GlobalTID(XID_FORMAT_ID, 0, 375 generateTID(localTID.longValue())); 376 377 379 state = STATE_NONE; 380 subordinate = false; 381 } 382 383 399 int reconstruct(CoordinatorLog log) { 400 401 int result = STATE_NONE; 402 403 405 logSection = log.createSection(LOG_SECTION_NAME); 406 byte[][] logData = log.getData(logSection); 407 408 410 int logState = 0; 411 for (int i = 0; i < logData.length; i++) { 412 if (logData[i].length > 1) { 413 logState |= (((logData[i][0] & 255) << 8) + 414 (logData[i][1] & 255)); 415 } else { 416 _logger.log(Level.SEVERE,"jts.invalid_log_record_data", 418 LOG_SECTION_NAME); 419 String msg = LogFormatter.getLocalizedMessage(_logger, 420 "jts.invalid_log_record_data", 421 new java.lang.Object [] { LOG_SECTION_NAME }); 422 throw new org.omg.CORBA.INTERNAL (msg); 423 } 424 } 425 426 428 if ((logState & (1 << STATE_ROLLED_BACK)) != 0) 429 result = STATE_ROLLED_BACK; 430 else if ((logState & (1 << STATE_COMMITTED)) != 0) 431 result = STATE_COMMITTED; 432 else if ((logState & (1 << STATE_COMMITTING)) != 0) 433 result = STATE_COMMITTING; 434 else if ((logState & (1 << STATE_ROLLING_BACK)) != 0) 435 result = STATE_ROLLING_BACK; 436 else if ((logState & (1 << STATE_PREPARED_READONLY)) != 0) 437 result = STATE_PREPARED_READONLY; 438 else if ((logState & (1 << STATE_PREPARED_FAIL)) != 0) 439 result = STATE_PREPARED_FAIL; 440 else if ((logState & (1 << STATE_PREPARED_SUCCESS)) != 0) 441 result = STATE_PREPARED_SUCCESS; 442 else if ((logState & (1 << STATE_COMMITTING_ONE_PHASE)) != 0) 444 result = STATE_COMMITTING_ONE_PHASE; 445 else if ((logState & (1 << STATE_COMMITTED_ONE_PHASE_OK)) != 0) 446 result = STATE_COMMITTED_ONE_PHASE_OK; 447 else if ((logState & (1 << STATE_COMMIT_ONE_PHASE_ROLLED_BACK)) != 0) 448 result = STATE_COMMIT_ONE_PHASE_ROLLED_BACK; 449 else if ((logState & 450 (1 << STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD)) != 0) 451 result = STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD; 452 else if ((logState & 453 (1 << STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED)) != 0) 454 result = STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED; 455 456 state = result; 457 subordinate = false; 458 logRecord = log; 459 460 return result; 461 } 462 463 472 public void finalize() { 473 474 state = STATE_NONE; 475 globalTID = null; 476 localTID = null; 477 logRecord = null; 478 logSection = null; 479 } 480 481 500 boolean setState(int newState) { 501 502 boolean result = false; 503 504 506 if (validStateChange[state][newState]) { 507 508 if(AdminUtil.bSampling) 510 { 511 switch ( newState ) 512 { 513 case STATE_PREPARED_SUCCESS : 514 AdminUtil.incrementPendingTransactionCount(); 515 break ; 516 case STATE_PREPARED_READONLY : 517 AdminUtil.incrementPendingTransactionCount(); 518 break ; 519 case STATE_COMMITTED : 520 AdminUtil.incrementCommitedTransactionCount(); 521 break ; 522 case STATE_ROLLED_BACK : 523 AdminUtil.incrementAbortedTransactionCount(); 524 break ; 525 533 case STATE_ROLLING_BACK : 534 AdminUtil.incrementUnpreparedAbortedTransactionCount(); 535 break; 536 } 537 } 538 539 540 switch ( state ) 542 { 543 case STATE_PREPARING : 544 case STATE_COMMITTING : 545 546 case STATE_COMMITTING_ONE_PHASE : 547 if(_logger.isLoggable(Level.FINEST)){ 548 String statestr=null; 549 switch(newState ) { 550 case STATE_PREPARING : 551 statestr="PREPARING"; 552 break; 553 case STATE_COMMITTING : 554 statestr="COMMITTING"; 555 break; 556 case STATE_COMMITTING_ONE_PHASE : 557 statestr="COMMITTING_ONE_PHASE"; 558 break; 559 default : 560 statestr="Illegal state "; 561 break; 562 } 563 _logger.logp(Level.FINEST,"TransactionState","setState()", 564 "Releasing read lock on freeze : state "+statestr); 565 } 566 freezeLock.releaseReadLock(); 567 if(_logger.isLoggable(Level.FINEST)){ 568 String statestr=null; 569 _logger.logp(Level.FINEST,"TransactionState","setState()", 570 "Released read lock on freeze"); 571 switch(newState ) { 572 case STATE_PREPARING : 573 statestr="PREPARING"; 574 break; 575 case STATE_COMMITTING : 576 statestr="COMMITTING"; 577 break; 578 case STATE_COMMITTING_ONE_PHASE : 579 statestr="COMMITTING_ONE_PHASE"; 580 break; 581 default : 582 statestr="Illegal state "; 583 break; 584 } 585 _logger.logp(Level.FINEST,"TransactionState","setState()", 586 "Released read lock on freeze : state "+statestr); 587 } 588 break; 589 } 590 591 switch ( newState ) 593 { 594 case STATE_PREPARING : 595 case STATE_COMMITTING : 596 case STATE_COMMITTING_ONE_PHASE : 598 if(_logger.isLoggable(Level.FINEST)){ 599 String statestr=null; 600 switch(newState ) { 601 case STATE_PREPARING : 602 statestr="PREPARING"; 603 break; 604 case STATE_COMMITTING : 605 statestr="COMMITTING"; 606 break; 607 case STATE_COMMITTING_ONE_PHASE : 608 statestr="COMMITTING_ONE_PHASE"; 609 break; 610 default : 611 statestr="Illegal state "; 612 break; 613 } 614 _logger.logp(Level.FINEST,"TransactionState","setState()", 615 "Acquiring read lock on freeze : state "+statestr); 616 } 617 freezeLock.acquireReadLock(); 618 if(_logger.isLoggable(Level.FINEST)){ 619 String statestr=null; 620 switch(newState ) { 621 case STATE_PREPARING : 622 statestr="PREPARING"; 623 break; 624 case STATE_COMMITTING : 625 statestr="COMMITTING"; 626 break; 627 case STATE_COMMITTING_ONE_PHASE : 628 statestr="COMMITTING_ONE_PHASE"; 629 break; 630 default : 631 statestr="Illegal state "; 632 break; 633 } 634 _logger.logp(Level.FINEST,"TransactionState","setState()", 635 "Acquired read lock on freeze : state "+statestr); 636 } 637 break; 638 } 639 640 if (FailureInducer.isFailureInducerActive() && 642 (!(Thread.currentThread().getName(). 643 equals("JTS Resync Thread")))) { 644 Integer failurePoint = null; 645 switch (newState) { 646 case STATE_PREPARING : 647 failurePoint = FailureInducer.ACTIVE; break; 648 case STATE_PREPARED_SUCCESS : 649 failurePoint = FailureInducer.PREPARING; break; 650 case STATE_PREPARED_FAIL : 651 failurePoint = FailureInducer.PREPARING; break; 652 case STATE_PREPARED_READONLY : 653 failurePoint = FailureInducer.PREPARING; break; 654 case STATE_COMMITTING_ONE_PHASE : 655 failurePoint = FailureInducer.ACTIVE; break; 656 case STATE_COMMITTED_ONE_PHASE_OK : 657 failurePoint = FailureInducer.COMPLETING; break; 658 case STATE_COMMIT_ONE_PHASE_ROLLED_BACK : 659 failurePoint = FailureInducer.COMPLETING; break; 660 case STATE_COMMITTING : 661 failurePoint = FailureInducer.PREPARED; break; 662 case STATE_COMMITTED : 663 failurePoint = FailureInducer.COMPLETING; break; 664 case STATE_ROLLING_BACK : 665 if (state == STATE_PREPARED_SUCCESS) { 666 failurePoint = FailureInducer.PREPARED; 667 } else if (state == STATE_PREPARED_FAIL) { 668 failurePoint = FailureInducer.PREPARED; 669 } else if (state == STATE_PREPARED_READONLY) { 670 failurePoint = FailureInducer.PREPARED; 671 } else if (state == STATE_ACTIVE) { 672 failurePoint = FailureInducer.ACTIVE; 673 } 674 break; 675 case STATE_ROLLED_BACK : 676 failurePoint = FailureInducer.COMPLETING; 677 } 678 FailureInducer.waitForFailure(this.globalTID, failurePoint); 679 } 680 681 684 state = newState; 685 result = true; 686 687 689 if (logRecord != null && 690 (newState == STATE_PREPARED_SUCCESS || 691 newState == STATE_PREPARED_FAIL || 692 (newState == STATE_COMMITTING && subordinate) || 693 (newState == STATE_ROLLING_BACK && subordinate) || 694 newState == STATE_COMMITTED || 695 newState == STATE_ROLLED_BACK || 696 newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD || 701 newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED 702 )) { 704 byte[] byteData = new byte[2]; 705 byteData[0] = (byte)(((1 << state) & 0xff00) >> 8); 706 byteData[1] = (byte)( (1 << state) & 0x00ff); 707 result = logRecord.addData(logSection, byteData); 708 } 709 710 716 if (logRecord != null && 717 (newState == STATE_PREPARED_SUCCESS || 718 723 newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD || 724 newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED || 725 (newState == STATE_COMMITTING && subordinate) || 727 (newState == STATE_ROLLING_BACK && subordinate))) { 728 729 733 setInDoubt(true); 734 735 738 if (!(result = logRecord.write(true))) { 739 } 741 } else { 742 if (newState == STATE_PREPARED_SUCCESS || 743 newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD || 744 newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED || 745 (newState == STATE_COMMITTING && subordinate) || 746 (newState == STATE_ROLLING_BACK && subordinate)) { 747 setInDoubt(true); 748 } 750 } 751 752 753 757 if (logRecord != null && (newState == STATE_COMMITTED || 758 newState == STATE_ROLLED_BACK)) { 762 763 765 if (!(result = logRecord.write(false))) { 766 } 768 } 769 770 if (FailureInducer.isFailureInducerActive() && 772 (!(Thread.currentThread().getName(). 773 equals("JTS Resync Thread")))) { 774 Integer failurePoint = null; 775 switch (newState) { 776 case STATE_COMMITTED_ONE_PHASE_OK : 777 failurePoint = FailureInducer.COMPLETED; break; 778 case STATE_COMMITTED : 779 failurePoint = FailureInducer.COMPLETED; break; 780 case STATE_ROLLED_BACK : 781 failurePoint = FailureInducer.COMPLETED; 782 } 783 FailureInducer.waitForFailure(this.globalTID, failurePoint); 784 } 785 } 786 787 return result; 788 } 789 790 799 private static synchronized long getSequenceNumber() { 800 801 return ++sequenceNumber; 802 } 803 804 813 819 820 829 static boolean inDoubt() { 830 return inDoubt; 831 } 832 833 842 static void setInDoubt(boolean value) { 843 inDoubt = value; 844 } 845 846 857 private static final byte[] generateTID(long localTID) { 858 if(TIDTemplate==null){ 859 synchronized(TransactionState.class){ 860 if(TIDTemplate==null){ 861 String serverName = Configuration.getServerName(); 862 int nameLength = (serverName == null ? 0 : serverName.length()); 863 TIDTemplate = new byte[nameLength+8]; 864 865 long epochNumber = new Date().getTime(); 866 TIDTemplate[4] = (byte) epochNumber; 867 TIDTemplate[5] = (byte)(epochNumber >> 8); 868 TIDTemplate[6] = (byte)(epochNumber >> 16); 869 TIDTemplate[7] = (byte)(epochNumber >> 24); 870 871 for( int i = 0; i < nameLength; i++ ) 872 TIDTemplate[i+8] = (byte) serverName.charAt(i); 873 } 874 } 875 } 876 byte[] result = new byte[TIDTemplate.length]; 877 System.arraycopy(TIDTemplate, 4, result, 4, TIDTemplate.length-4); 878 879 result[0] = (byte) localTID; 880 result[1] = (byte)(localTID >> 8); 881 result[2] = (byte)(localTID >> 16); 882 result[3] = (byte)(localTID >> 24); 883 884 return result; 885 } 886 } 887 | Popular Tags |