1 47 package org.objectweb.jotm; 48 49 import java.rmi.RemoteException ; 50 import java.rmi.NoSuchObjectException ; 51 import java.rmi.ServerException ; 52 53 import javax.rmi.PortableRemoteObject ; 54 55 import java.util.List ; 56 import java.util.ArrayList ; 57 import javax.transaction.Status ; 58 import javax.transaction.TransactionRolledbackException ; 59 import javax.transaction.xa.Xid ; 60 61 import org.objectweb.carol.util.configuration.ConfigurationRepository; 62 import org.objectweb.carol.rmi.exception.RmiUtility; 63 64 72 public class ControlImpl 73 extends PortableRemoteObject 74 implements Control, Resource, Coordinator, Terminator , RecoveryCoordinator, TimerEventListener { 75 76 82 private List resourceList = new ArrayList (); 83 86 private List synchronizationList = new ArrayList (); 87 90 private int mystatus = Status.STATUS_UNKNOWN; 91 94 private boolean hasSupCoord = false; 95 98 private TimerEvent mytimer = null; 99 102 private Xid xid; 103 106 private Log mylog; 107 108 112 120 ControlImpl(int timeout, Xid x, Object supco) throws RemoteException { 121 if (TraceTm.jotm.isDebugEnabled()) { 122 TraceTm.jotm.debug("timeout="+ timeout +", xid="+ x +", supco="+ supco); 123 } 124 125 mystatus = Status.STATUS_ACTIVE; 127 xid = x; 128 hasSupCoord = (supco != null); 129 130 132 mytimer = TimerManager.getInstance().addTimer(this, timeout, new Integer (1), false); 133 134 if (supco != null) { 136 try { 137 if (supco instanceof Coordinator) 138 ((Coordinator) supco).register_resource(this); 139 else 140 throw new RemoteException ("Not Implemented"); 144 } catch (Exception e) { 145 TraceTm.jotm.error("Cannot register sub-coordinator:\n", e); 146 } 147 } 148 } 149 150 154 159 public Terminator get_terminator() throws RemoteException { 160 161 return this; 162 } 163 164 169 public Coordinator get_coordinator() throws RemoteException { 170 if (TraceTm.jotm.isDebugEnabled()) { 171 TraceTm.jotm.debug("ControlImpl.get_coordinator"); 172 } 173 return this; 174 } 175 176 180 185 public int get_status() throws RemoteException { 186 if (TraceTm.jotm.isDebugEnabled()) { 187 TraceTm.jotm.debug("ControlImpl.get_status()"); 188 } 189 return mystatus; 190 } 191 192 198 public boolean is_same_transaction(Coordinator tc) throws RemoteException { 199 if (TraceTm.jotm.isDebugEnabled()) { 200 TraceTm.jotm.debug("ControlImpl.is_same_transaction(Coordinator)"); 201 } 202 203 String other = null; 204 205 try { 206 other = tc.get_transaction_name(); 207 } catch (Exception e) { 208 if (TraceTm.jotm.isDebugEnabled()) { 209 TraceTm.jotm.error("ControlImpl.is_same_transaction() raised exception:\n", e); 210 } 211 return false; 212 } 213 214 return other.equals(get_transaction_name()); 215 } 216 217 223 public synchronized RecoveryCoordinator register_resource(Resource res) throws RemoteException { 224 if (TraceTm.jotm.isDebugEnabled()) { 225 TraceTm.jotm.debug("resource="+ res); 226 TraceTm.jotm.debug("mystatus="+ StatusHelper.getStatusName(mystatus)); 227 } 228 229 switch (mystatus) { 230 231 case Status.STATUS_ACTIVE : 232 resourceList.add(res); 234 if (TraceTm.jotm.isDebugEnabled()) { 235 TraceTm.jotm.debug("Resource registered"); 236 } 237 break; 238 239 case Status.STATUS_MARKED_ROLLBACK : 240 case Status.STATUS_ROLLEDBACK : 241 case Status.STATUS_ROLLING_BACK : 242 TraceTm.jotm.error("ControlImpl.register_resource(): Transaction Rolled back"); 243 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 244 throw new TransactionRolledbackException (); 245 246 default : 247 TraceTm.jotm.error("ControlImpl.register_resource(): Transaction Inactive"); 248 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 249 throw new InactiveException("Cannot register resource, status " + StatusHelper.getStatusName(mystatus)); 250 } 251 return this; 252 } 253 254 259 public synchronized void register_synchronization(RemoteSynchro sync) throws RemoteException { 260 if (TraceTm.jotm.isDebugEnabled()) { 261 TraceTm.jotm.debug("sync="+ sync); 262 TraceTm.jotm.debug("mystatus="+ StatusHelper.getStatusName(mystatus)); 263 } 264 265 switch (mystatus) { 266 267 case Status.STATUS_ACTIVE : 268 synchronizationList.add(sync); 270 if (TraceTm.jotm.isDebugEnabled()) { 271 TraceTm.jotm.debug("ControlImpl.register_synchronization(): RemoteSynchro registered"); 272 } 273 break; 274 275 case Status.STATUS_MARKED_ROLLBACK : 276 case Status.STATUS_ROLLEDBACK : 277 case Status.STATUS_ROLLING_BACK : 278 TraceTm.jotm.error("ControlImpl.register_synchronization(): Transaction Rolled back"); 279 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 280 throw new TransactionRolledbackException (); 281 282 default : 283 TraceTm.jotm.error("ControlImpl.register_synchronization(): Transaction Inactive"); 284 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 285 throw new InactiveException("Cannot register synchronization, status " + StatusHelper.getStatusName(mystatus)); 286 } 287 } 288 289 293 public synchronized void rollback_only() throws RemoteException { 294 if (TraceTm.jotm.isDebugEnabled()) { 295 TraceTm.jotm.debug("mystatus="+ StatusHelper.getStatusName(mystatus)); 296 } 297 298 switch (mystatus) { 299 300 case Status.STATUS_MARKED_ROLLBACK : 301 if (TraceTm.jotm.isDebugEnabled()) { 303 TraceTm.jotm.debug("ControlImpl.rollback_only(): Already marked rolledback"); 304 } 305 break; 306 307 case Status.STATUS_ACTIVE : 308 mystatus = Status.STATUS_MARKED_ROLLBACK; 310 if (TraceTm.jotm.isDebugEnabled()) { 311 TraceTm.jotm.debug("ControlImpl.rollback_only(): Marked rollback"); 312 } 313 break; 314 315 default : 316 TraceTm.jotm.error("ControlImpl.rollback_only(): Inactive"); 318 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 319 throw new InactiveException("Cannot rollback transaction, status " + StatusHelper.getStatusName(mystatus)); 320 } 321 } 322 323 330 public String get_transaction_name() throws RemoteException { 331 if (TraceTm.jotm.isDebugEnabled()) { 332 TraceTm.jotm.debug("ControlImpl.get_transaction_name()"); 333 } 334 335 return xid.toString(); 336 } 337 338 342 351 public synchronized void commit(boolean report_heuristics) throws RemoteException { 352 if (TraceTm.jotm.isDebugEnabled()) { 353 TraceTm.jotm.debug("report_heuristics="+ report_heuristics); 354 TraceTm.jotm.debug("mystatus="+ StatusHelper.getStatusName(mystatus)); 355 } 356 357 String protocol = ConfigurationRepository.getCurrentConfiguration().getProtocol().getName(); 358 359 if (mytimer != null) { 361 mytimer.stop(); 362 } 363 364 switch (mystatus) { 366 367 case Status.STATUS_ACTIVE : 368 break; 370 371 case Status.STATUS_COMMITTED : 372 TraceTm.jotm.error("ControlImpl.commit(boolean): already done"); 373 return; 374 375 case Status.STATUS_ROLLEDBACK : 376 TraceTm.jotm.error("ControlImpl.commit(boolean): already rolled back"); 377 completed(true); 380 381 if (protocol == null || !(protocol.equals("iiop"))) { 382 throw new TransactionRolledbackException (); 383 } 384 385 RmiUtility.rethrowRmiException(new TransactionRolledbackException ()); 386 387 case Status.STATUS_MARKED_ROLLBACK : 388 int errors = do_before_completion(); 390 391 if (errors > 0) { 392 TraceTm.jotm.info("ControlImpl.commit(boolean): before completion error at rollback"); 393 } 394 395 do_rollback(report_heuristics); 396 completed(true); 397 398 if (protocol == null || !(protocol.equals("iiop"))) { 399 throw new TransactionRolledbackException (); 400 } 401 402 RmiUtility.rethrowRmiException(new TransactionRolledbackException ()); 403 404 default : 405 TraceTm.jotm.error("ControlImpl.commit(boolean): bad status"); 406 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 407 408 if (protocol == null || !(protocol.equals("iiop"))) { 409 throw new HeuristicMixed(); 410 } 411 412 RmiUtility.rethrowRmiException(new HeuristicMixed()); 413 } 414 415 if (resourceList.size() == 1) { 418 TraceTm.jotm.debug("1 resource"); 419 420 int errors = do_before_completion(); 422 423 if (errors > 0) { 424 TraceTm.jotm.info("before completion error -> rollback"); 425 do_rollback(report_heuristics); 426 completed(true); 427 428 if (protocol == null || !(protocol.equals("iiop"))) { 429 throw new TransactionRolledbackException (); 430 } 431 432 RmiUtility.rethrowRmiException(new TransactionRolledbackException ()); 433 } 434 435 mystatus = Status.STATUS_COMMITTING; 436 437 try { 438 Resource res = (Resource) resourceList.get(0); 439 res.commit_one_phase(); 440 mystatus = Status.STATUS_COMMITTED; 441 } catch (TransactionRolledbackException e) { 442 TraceTm.jotm.info("commit_one_phase = TransactionRolledbackException"); 443 mystatus = Status.STATUS_ROLLEDBACK; 444 } catch (HeuristicHazard e) { 445 TraceTm.jotm.info("commit_one_phase = HeuristicException"); 446 mystatus = Status.STATUS_UNKNOWN; 447 } catch (NoSuchObjectException e) { 448 TraceTm.jotm.info("commit_one_phase = NoSuchObjectException"); 450 mystatus = Status.STATUS_ROLLEDBACK; 451 } catch (ServerException e) { TraceTm.jotm.info("commit_one_phase = ServerException: "+ e); 453 mystatus = Status.STATUS_ROLLEDBACK; 454 } catch (Exception e) { 455 TraceTm.jotm.error("commit_one_phase = Unexpected exception: ", e); 456 mystatus = Status.STATUS_UNKNOWN; 457 } 458 459 do_after_completion(); 461 462 switch (mystatus) { 464 case Status.STATUS_COMMITTED : 465 completed(true); 466 break; 467 case Status.STATUS_ROLLEDBACK : 468 completed(true); 469 470 if (protocol == null || !(protocol.equals("iiop"))) { 471 throw new TransactionRolledbackException (); 472 } 473 474 RmiUtility.rethrowRmiException(new TransactionRolledbackException ()); 475 case Status.STATUS_UNKNOWN : 476 completed(false); 477 478 if (report_heuristics) { 479 if (protocol == null || !(protocol.equals("iiop"))) { 480 throw new HeuristicHazard(); 481 } 482 483 RmiUtility.rethrowRmiException(new HeuristicHazard()); 484 } 485 } 486 return; 487 } 488 489 int v = do_prepare(report_heuristics); 491 492 if (TraceTm.jotm.isDebugEnabled()) { 493 TraceTm.jotm.debug("Vote = " + v); 494 } 495 496 switch (v) { 498 case Resource.VOTE_COMMIT : 499 if (TraceTm.jotm.isDebugEnabled()) { 500 TraceTm.jotm.debug("ControlImpl.commit(boolean): committing Tx"); 501 } 502 break; 503 case Resource.VOTE_ROLLBACK : 504 if (TraceTm.jotm.isDebugEnabled()) { 505 TraceTm.jotm.debug("ControlImpl.commit(boolean): rolling back Tx"); 506 } 507 do_rollback(report_heuristics); 508 completed(true); 509 510 if (protocol == null || !(protocol.equals("iiop"))) { 511 throw new TransactionRolledbackException (); 512 } 513 514 RmiUtility.rethrowRmiException(new TransactionRolledbackException ()); 515 case Resource.VOTE_READONLY : 516 if (TraceTm.jotm.isDebugEnabled()) { 518 TraceTm.jotm.debug("ControlImpl.commit(boolean): readonly resources"); 519 } 520 mystatus = Status.STATUS_COMMITTED; 521 completed(true); 522 return; 523 } 524 525 mylog.flushLog(Log.DECISION_TO_COMMIT); 527 528 if (do_commit(report_heuristics) == 0) { 530 completed(true); 531 } else { 532 completed(false); 533 } 534 } 535 536 541 546 public synchronized void rollback() throws RemoteException { 547 if (TraceTm.jotm.isDebugEnabled()) { 548 TraceTm.jotm.debug("mystatus="+ StatusHelper.getStatusName(mystatus)); 549 } 550 551 String protocol = ConfigurationRepository.getCurrentConfiguration().getProtocol().getName(); 552 553 if (mytimer != null) { 555 mytimer.stop(); 556 } 557 558 switch (mystatus) { 560 561 case Status.STATUS_ACTIVE : 562 case Status.STATUS_MARKED_ROLLBACK : 563 break; 565 566 case Status.STATUS_ROLLEDBACK : 567 TraceTm.jotm.error("ControlImpl.rollback(): already rolled back"); 568 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 569 return; 570 571 default : 572 TraceTm.jotm.error("ControlImpl.rollback(): rollback: bad status"); 573 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 574 completed(false); 575 576 if (protocol == null || !(protocol.equals("iiop"))) { 577 throw new HeuristicMixed("rollback: bad status"); 578 } 579 580 RmiUtility.rethrowRmiException(new TransactionRolledbackException ()); 581 } 582 583 if (!hasSupCoord) { 585 int errors = do_before_completion(); 587 if (errors > 0) { 588 TraceTm.jotm.info("ControlImpl.rollback(): before completion error at rollback"); 589 } 590 } 591 592 try { 594 do_rollback(false); 595 } catch (Exception e) { 596 TraceTm.jotm.error("ControlImpl.rollback(): rollback raised exception ", e); 597 } 598 completed(true); 599 } 600 601 605 611 public synchronized int prepare() throws RemoteException { 612 if (TraceTm.jotm.isDebugEnabled()) { 613 TraceTm.jotm.debug("mystatus="+ StatusHelper.getStatusName(mystatus)); 614 } 615 616 if (mytimer != null) { 618 mytimer.stop(); 619 } 620 621 switch (mystatus) { 623 624 case Status.STATUS_ACTIVE : 625 break; 627 628 case Status.STATUS_COMMITTED : 629 TraceTm.jotm.error("ControlImpl.prepare(): transaction already commited"); 631 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 632 return Resource.VOTE_COMMIT; 633 634 case Status.STATUS_ROLLEDBACK : 635 TraceTm.jotm.error("ControlImpl.prepare(): transaction already rolled back"); 637 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 638 return Resource.VOTE_ROLLBACK; 639 640 case Status.STATUS_MARKED_ROLLBACK : 641 do_rollback(false); 642 completed(true); 643 return Resource.VOTE_ROLLBACK; 644 645 default : 646 TraceTm.jotm.error("ControlImpl.prepare(): bad status"); 648 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 649 completed(false); 650 return Resource.VOTE_ROLLBACK; 651 } 652 653 int ret = do_prepare(false); 654 655 switch (ret) { 656 case Resource.VOTE_COMMIT : 657 if (TraceTm.jotm.isDebugEnabled()) { 658 TraceTm.jotm.debug("ControlImpl.prepare(): vote commit"); 659 } 660 break; 661 case Resource.VOTE_ROLLBACK : 662 if (TraceTm.jotm.isDebugEnabled()) { 663 TraceTm.jotm.debug("ControlImpl.prepare(): vote rollback"); 664 } 665 do_rollback(false); 666 completed(true); 667 return ret; 668 case Resource.VOTE_READONLY : 669 if (TraceTm.jotm.isDebugEnabled()) { 670 TraceTm.jotm.debug("ControlImpl.prepare(): vote readonly"); 671 } 672 mystatus = Status.STATUS_COMMITTED; 673 completed(true); 674 return ret; 675 } 676 677 680 return ret; 681 } 682 683 687 public synchronized void commit() throws RemoteException { 688 if (TraceTm.jotm.isDebugEnabled()) { 689 TraceTm.jotm.debug("mystatus="+ StatusHelper.getStatusName(mystatus)); 690 } 691 692 switch (mystatus) { 694 case Status.STATUS_PREPARED : 695 break; 697 default : 698 TraceTm.jotm.error("ControlImpl.commit(): commit: bad status"); 700 TraceTm.jotm.error("mystatus= "+ StatusHelper.getStatusName(mystatus)); 701 completed(false); 702 return; 703 } 704 705 if (do_commit(true) == 0) { 707 completed(true); 708 } else { 709 completed(false); 710 } 711 } 712 713 717 public void commit_one_phase() throws RemoteException { 718 if (TraceTm.jotm.isDebugEnabled()) { 719 TraceTm.jotm.debug("ControlImpl.commit_one_phase()"); 720 } 721 722 commit(true); 724 } 725 726 730 public synchronized void forget() throws RemoteException { 731 if (TraceTm.jotm.isDebugEnabled()) { 732 TraceTm.jotm.debug("ControlImpl.forget()"); 733 } 734 735 completed(true); 736 } 737 738 742 747 public int replay_completion(Resource res) throws RemoteException { 748 if (TraceTm.jotm.isDebugEnabled()) { 749 TraceTm.jotm.debug("res="+ res); 750 } 751 return mystatus; 752 } 753 754 758 762 public void timeoutExpired(Object arg) { 763 if (TraceTm.jotm.isDebugEnabled()) { 764 TraceTm.jotm.debug("arg="+ arg); 765 } 766 767 int argvalue = ((Integer ) arg).intValue(); 768 769 switch (argvalue) { 770 case 1 : 771 if (TraceTm.jotm.isDebugEnabled()) { 772 TraceTm.jotm.debug("ControlImpl.timeoutExpired(Object): timeout expired"); 773 } 774 775 try { 776 do_rollback(false); 777 } catch (Exception e) { 778 TraceTm.jotm.error("ControlImpl.timeoutExpired(Object): rollback raised exception ", e); 779 } 780 break; 781 case 2 : 782 if (TraceTm.jotm.isDebugEnabled()) { 783 TraceTm.jotm.debug("ControlImpl.timeoutExpired(Object): removing ControlImpl"); 784 } 785 explicit_destroy(); 786 break; 787 default : 788 TraceTm.jotm.error("ControlImpl.timeoutExpired(Object): timeoutExpired bad value="+ argvalue); 789 break; 790 } 791 } 792 793 797 801 void ding() { 802 if (TraceTm.jotm.isDebugEnabled()) { 803 TraceTm.jotm.debug(""); 804 } 805 } 806 807 815 private int do_prepare(boolean report_heuristics) { 816 if (TraceTm.jotm.isDebugEnabled()) { 817 TraceTm.jotm.debug("report_heuristics="+ report_heuristics); 818 } 819 820 int errors = 0; 821 int ret = Resource.VOTE_READONLY; 822 823 errors = do_before_completion(); 825 826 if (errors > 0) { 827 if (TraceTm.jotm.isDebugEnabled()) { 828 TraceTm.jotm.debug("before_completion failed -> rollback"); 829 } 830 return Resource.VOTE_ROLLBACK; 831 } 832 833 if (resourceList.size() == 0) { 835 TraceTm.jotm.error("commit: no resource"); 836 mystatus = Status.STATUS_COMMITTED; 837 do_after_completion(); 838 completed(true); 839 return ret; 840 } 841 842 mylog = new Log(); 846 847 mystatus = Status.STATUS_PREPARING; 852 853 for (int i = 0; i < resourceList.size(); i++) { 854 Resource res = (Resource) resourceList.get(i); 855 856 if (errors > 0) { 857 if (TraceTm.jotm.isWarnEnabled()) { 858 TraceTm.jotm.warn("Vote stopped: at least one resource has voted rollback."); 859 } 860 break; 861 } else { 862 try { 864 if (TraceTm.jotm.isDebugEnabled()) { 865 TraceTm.jotm.debug("send prepare to resource"); 866 } 867 868 switch (res.prepare()) { 869 case Resource.VOTE_COMMIT : 870 mylog.addResource(res); 872 TraceTm.jotm.info("Resource replied commit to prepare"); 873 ret = Resource.VOTE_COMMIT; 874 break; 875 case Resource.VOTE_ROLLBACK : 876 TraceTm.jotm.info("Resource replied rollback to prepare"); 877 ret = Resource.VOTE_ROLLBACK; 878 errors++; 879 break; 880 case Resource.VOTE_READONLY : 881 if (TraceTm.jotm.isDebugEnabled()) { 882 TraceTm.jotm.debug("Resource replied readonly to prepare"); 883 } 884 break; 885 } 886 } catch (HeuristicHazard e) { TraceTm.jotm.error("HeuristicHazard on prepare"); 888 ret = Resource.VOTE_ROLLBACK; 889 errors++; 890 } catch (HeuristicMixed e) { TraceTm.jotm.error("HeuristicMixed on prepare"); 892 ret = Resource.VOTE_ROLLBACK; 893 errors++; 894 } catch (Exception e) { 895 TraceTm.jotm.error("exception on prepare: ", e); 896 ret = Resource.VOTE_ROLLBACK; 897 errors++; 898 } 899 } 900 } 901 902 if (ret == Resource.VOTE_READONLY) { 903 if (TraceTm.jotm.isDebugEnabled()) { 904 TraceTm.jotm.debug("All resources returned Readonly"); 905 } 906 mystatus = Status.STATUS_COMMITTED; 907 do_after_completion(); 909 } 910 if (ret == Resource.VOTE_COMMIT) { 911 mystatus = Status.STATUS_PREPARED; 912 } 913 914 if (TraceTm.jotm.isDebugEnabled()) { 915 if (TraceTm.jotm.isDebugEnabled()) { 916 TraceTm.jotm.debug("Vote = " + ret); 917 } 918 } 919 return ret; 920 } 921 922 930 private int do_commit(boolean report_heuristics) 931 throws TransactionRolledbackException , HeuristicMixed, HeuristicHazard, HeuristicRollback { 932 933 if (TraceTm.jotm.isDebugEnabled()) { 934 TraceTm.jotm.debug("report_heuristics="+ report_heuristics); 935 } 936 937 if (mylog == null) { 939 TraceTm.jotm.error("no log"); 940 return -1; 941 } 942 943 mystatus = Status.STATUS_COMMITTING; 945 946 int commitnb = 0; 948 int heuristicnb = 0; 949 int errors = 0; 950 int heuristicstate = 0; 951 952 for (int i = 0; i < mylog.resourceLogged.size(); i++) { 953 ResourceInfo resinfo = (ResourceInfo) mylog.resourceLogged.elementAt(i); 954 955 if (resinfo.mystate != ResourceInfo.PREPARED) { 956 TraceTm.jotm.info("resource not prepared"); 957 continue; 958 } 959 960 if (commitnb == 0 && errors > 0) { 962 try { 963 TraceTm.jotm.info("Send rollback to resource"); 964 resinfo.getResource().rollback(); 965 resinfo.mystate = ResourceInfo.ROLLEDBACK; 966 } catch (HeuristicCommit e) { 967 TraceTm.jotm.error("Heuristic commit"); 968 resinfo.mystate = ResourceInfo.HEURISTIC_COMMIT; 969 heuristicstate = ResourceInfo.HEURISTIC_COMMIT; 970 commitnb++; 971 heuristicnb++; 972 } catch (Exception e) { 973 TraceTm.jotm.error("exception on rollback: ", e); 974 } 975 continue; 976 } 977 978 980 try { 981 TraceTm.jotm.debug("Send commit to resource"); 982 resinfo.getResource().commit(); 983 resinfo.mystate = ResourceInfo.COMMITTED; 984 commitnb++; 985 } catch (HeuristicRollback e) { 986 TraceTm.jotm.error("Heuristic Rollback"); 987 resinfo.mystate = ResourceInfo.HEURISTIC_ROLLBACK; 988 heuristicstate = ResourceInfo.HEURISTIC_ROLLBACK; 989 errors++; 990 if (commitnb > 0) 991 heuristicnb++; 992 } catch (HeuristicMixed e) { 993 TraceTm.jotm.error("Heuristic Mixed"); 994 resinfo.mystate = ResourceInfo.HEURISTIC_MIXED; 995 heuristicstate = ResourceInfo.HEURISTIC_MIXED; 996 errors++; 997 commitnb++; 998 heuristicnb++; 999 } catch (HeuristicHazard e) { 1000 TraceTm.jotm.error("Heuristic Hazard"); 1001 resinfo.mystate = ResourceInfo.HEURISTIC_HAZARD; 1002 heuristicstate = ResourceInfo.HEURISTIC_HAZARD; 1003 errors++; 1004 commitnb++; 1005 heuristicnb++; 1006 } catch (NotPreparedException e) { 1007 TraceTm.jotm.error("Resource Not Prepared"); 1008 resinfo.mystate = ResourceInfo.REGISTERED; 1009 errors++; 1010 } catch (NoSuchObjectException e) { 1011 TraceTm.jotm.error("invalid objref - assume committed"); 1012 resinfo.mystate = ResourceInfo.COMMITTED; 1013 commitnb++; 1014 } catch (Exception e) { 1015 TraceTm.jotm.error("exception on commit: ", e); 1016 errors++; 1017 } 1018 } 1019 1020 if (errors == 0) { 1021 if (TraceTm.jotm.isDebugEnabled()) { 1023 TraceTm.jotm.debug("transaction committed"); 1024 } 1025 1026 mystatus = Status.STATUS_COMMITTED; 1027 mylog.forgetLog(); 1028 do_after_completion(); 1030 return 0; 1031 } 1032 1033 if (heuristicnb == 0) { 1034 TraceTm.jotm.info("transaction rolled back"); 1036 mystatus = Status.STATUS_ROLLEDBACK; 1037 mylog.forgetLog(); 1038 do_after_completion(); 1040 throw new TransactionRolledbackException (); 1041 } 1042 1043 TraceTm.jotm.info("Heuristics must be logged"); 1045 mystatus = Status.STATUS_UNKNOWN; 1046 mylog.updateLog(); 1047 1048 do_after_completion(); 1050 1051 if (report_heuristics) { 1052 switch (heuristicstate) { 1053 case (ResourceInfo.HEURISTIC_ROLLBACK): { 1054 throw new HeuristicRollback(); 1055 } 1056 case (ResourceInfo.HEURISTIC_MIXED): { 1057 throw new HeuristicMixed(); 1058 } 1059 case (ResourceInfo.HEURISTIC_HAZARD): { 1060 throw new HeuristicHazard(); 1061 } 1062 } 1063 } 1064 1065 return -1; 1066 } 1067 1068 1073 private void do_rollback(boolean report_heuristics) throws HeuristicMixed { 1074 if (TraceTm.jotm.isDebugEnabled()) { 1075 TraceTm.jotm.debug("report_heuristics="+ report_heuristics); 1076 } 1077 1078 mystatus = Status.STATUS_ROLLEDBACK; 1079 1080 int commitnb = 0; 1082 1083 for (int i = 0; i < resourceList.size(); i++) { 1084 Resource res = (Resource) resourceList.get(i); 1085 try { 1086 if (TraceTm.jotm.isDebugEnabled()) { 1087 TraceTm.jotm.debug("Send rollback to Resource"); 1088 } 1089 res.rollback(); 1090 } catch (HeuristicCommit e) { 1091 TraceTm.jotm.error("Rollback raised HeuristicCommit"); 1092 commitnb++; 1093 } catch (Exception e) { 1094 TraceTm.jotm.error("Cannot rollback resource: ", e); 1095 } 1096 } 1097 1098 do_after_completion(); 1100 1101 if (commitnb > 0 && report_heuristics) { 1102 throw new HeuristicMixed(); 1104 } 1105 } 1106 1107 1110 private void explicit_destroy() { 1111 if (TraceTm.jotm.isDebugEnabled()) { 1112 TraceTm.jotm.debug(""); 1113 } 1114 1115 try { 1117 unexportObject(this); 1118 } catch (Exception e) {} 1119 } 1120 1121 1127 private void completed(boolean removeit) { 1128 if (TraceTm.jotm.isDebugEnabled()) { 1129 TraceTm.jotm.debug("removeit="+ removeit); 1130 } 1131 1132 if (mytimer != null) { 1133 if (removeit) { 1134 mytimer.change(60, new Integer (2)); 1136 } else { 1137 mytimer.unset(); 1140 mytimer = null; 1141 } 1142 } 1143 } 1144 1145 1150 private int do_before_completion() { 1151 if (TraceTm.jotm.isDebugEnabled()) { 1152 TraceTm.jotm.debug("ControlImpl.do_before_completion()"); 1153 TraceTm.jotm.debug("synchronizationList.size()="+ synchronizationList.size()); 1154 } 1155 1156 int errors = 0; 1157 1158 for (int i = 0; i < synchronizationList.size(); i++) { 1159 1160 RemoteSynchro sync = (RemoteSynchro) synchronizationList.get(i); 1161 1162 try { 1163 sync.before_completion(this); 1164 } catch (Exception e) { 1165 TraceTm.jotm.error("before_completion raised exception ", e); 1166 errors++; 1167 } 1168 } 1169 return errors; 1170 } 1171 1172 1175 private void do_after_completion() { 1176 1177 if (TraceTm.jotm.isDebugEnabled()) { 1178 TraceTm.jotm.debug("ControlImpl.do_after_completion()"); 1179 TraceTm.jotm.debug("status="+ mystatus); 1180 TraceTm.jotm.debug("synchronizationList.size()="+ synchronizationList.size()); 1181 } 1182 1183 for (int i = 0; i < synchronizationList.size(); i++) { 1184 RemoteSynchro sync = (RemoteSynchro) synchronizationList.get(i); 1185 1186 try { 1187 sync.after_completion(this, mystatus); 1188 } catch (Exception e) { 1189 TraceTm.jotm.error("after_completion raised exception ", e); 1190 } 1191 } 1192 } 1193} 1194 | Popular Tags |