1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.sun.jini.mahalo;
21
22 import java.io.Serializable;
23 import java.rmi.RemoteException;
24 import java.util.Date;
25 import java.util.Enumeration;
26 import java.util.List;
27 import java.util.Vector;
28 import java.util.logging.Level;
29 import java.util.logging.Logger;
30
31 import jgroup.jini.txn.InternalPassiveGroupTransactionManager;
32
33 import net.jini.core.transaction.CannotAbortException;
34 import net.jini.core.transaction.CannotCommitException;
35 import net.jini.core.transaction.CannotJoinException;
36 import net.jini.core.transaction.TimeoutExpiredException;
37 import net.jini.core.transaction.Transaction;
38 import net.jini.core.transaction.TransactionException;
39 import net.jini.core.transaction.UnknownTransactionException;
40 import net.jini.core.transaction.server.CrashCountException;
41 import net.jini.core.transaction.server.ServerTransaction;
42 import net.jini.core.transaction.server.TransactionConstants;
43 import net.jini.core.transaction.server.TransactionManager;
44 import net.jini.core.transaction.server.TransactionParticipant;
45 import net.jini.id.Uuid;
46 import net.jini.security.ProxyPreparer;
47
48 import com.sun.jini.constants.TimeConstants;
49 import com.sun.jini.constants.TxnConstants;
50 import com.sun.jini.landlord.LeasedResource;
51 import com.sun.jini.logging.Levels;
52 import com.sun.jini.mahalo.log.ClientLog;
53 import com.sun.jini.mahalo.log.LogException;
54 import com.sun.jini.mahalo.log.LogManager;
55 import com.sun.jini.thread.TaskManager;
56 import com.sun.jini.thread.WakeupManager;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public class GroupTxnManagerTransaction
76 implements TransactionConstants, TimeConstants, LeasedResource, Serializable
77 {
78
79
80
81
82
83 private final static org.apache.log4j.Logger log = org.apache.log4j.Logger
84 .getLogger(GroupTxnManagerTransaction.class);
85
86 private static final long serialVersionUID = -2088463193687796098L;
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 private static final boolean states[][] = {
129
130
131
132
133
134
135
136
137
138
139
140 private List parts = new Vector();
141
142
143
144
145 private final ServerTransaction str;
146
147
148
149
150 private int trstate;
151
152
153
154
155 private long expires;
156
157
158
159
160 private transient LogManager logmgr;
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195 private transient TaskManager threadpool;
196
197
198
199
200 private transient WakeupManager wm;
201
202
203
204
205 private transient TxnSettler settler;
206
207
208
209
210 private transient Job job;
211
212
213
214
215 private Uuid uuid;
216
217
218
219
220
221
222
223
224 private transient Object leaseLock = new Object();
225
226
227
228
229
230
231
232
233
234
235
236
237 private transient Object jobLock = new Object();
238
239
240
241
242
243
244
245
246
247
248
249
250 private transient Object stateLock = new Object();
251
252
253
254 private static final Logger operationsLogger =
255 TxnManagerImpl.operationsLogger;
256
257
258 private static final Logger transactionsLogger =
259 TxnManagerImpl.transactionsLogger;
260
261
262
263
264
265
266 private final long id;
267
268
269 private boolean backupsCommitted = false;
270
271
272 private long startprepare;
273
274
275 private long endprepare;
276
277
278 private long startcommit;
279
280
281 private long endcommit;
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302 GroupTxnManagerTransaction(TransactionManager mgr, LogManager logmgr, long id,
303 TaskManager threadpool, WakeupManager wm, TxnSettler settler,
304 Uuid uuid)
305 {
306 if (logmgr == null)
307 throw new IllegalArgumentException("GroupTxnManagerTransaction: " +
308 "log manager must be non-null");
309 if (mgr == null)
310 throw new IllegalArgumentException("GroupTxnManagerTransaction: " +
311 "transaction manager must be non-null");
312
313 if (threadpool == null)
314 throw new IllegalArgumentException("GroupTxnManagerTransaction: " +
315 "threadpool must be non-null");
316
317 if (wm == null)
318 throw new IllegalArgumentException("GroupTxnManagerTransaction: " +
319 "wakeup manager must be non-null");
320
321 if (settler == null)
322 throw new IllegalArgumentException("GroupTxnManagerTransaction: " +
323 "settler must be non-null");
324
325 if (uuid == null)
326 throw new IllegalArgumentException("GroupTxnManagerTransaction: " +
327 "uuid must be non-null");
328
329 this.threadpool = threadpool;
330 this.wm = wm;
331 this.logmgr = logmgr ;
332 str = new ServerTransaction(mgr, id);
333 this.settler = settler;
334 this.uuid = uuid;
335
336
337 this.id = id;
338
339 trstate = ACTIVE;
340
341
342 }
343
344
345
346
347
348
349
350
351
352 void add(ParticipantHandle handle)
353 throws InternalManagerException
354 {
355 if (operationsLogger.isLoggable(Level.FINER)) {
356 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
357 "add", handle);
358 }
359
360 if (handle == null)
361 throw new NullPointerException("ParticipantHolder: add: " +
362 "cannot add null handle");
363
364
365
366
367 try {
368 if (transactionsLogger.isLoggable(Level.FINEST)) {
369 transactionsLogger.log(Level.FINEST,
370 "Adding ParticipantHandle: {0}", handle);
371 }
372 parts.add(handle);
373 } catch (Exception e) {
374 if (transactionsLogger.isLoggable(Level.SEVERE)) {
375 transactionsLogger.log(Level.SEVERE,
376 "Unable to add ParticipantHandle", e);
377 }
378 throw new InternalManagerException("GroupTxnManagerTransaction: " +
379 "add: " + e.getMessage());
380 }
381 if (operationsLogger.isLoggable(Level.FINER)) {
382 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
383 "add");
384 }
385 }
386
387
388
389
390
391
392
393
394
395 void modifyParticipant(ParticipantHandle handle, int state) {
396 if (operationsLogger.isLoggable(Level.FINER)) {
397 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
398 "modifyParticipant", new Object[] {handle, new Integer(state)});
399 }
400 ParticipantHandle ph = null;
401
402 if (handle == null)
403 throw new NullPointerException("ParticipantHolder: " +
404 "modifyParticipant: cannot modify null handle");
405
406 if (parts.contains(ph))
407 ph = (ParticipantHandle) parts.get(parts.indexOf(handle));
408
409 if (ph == null) {
410 if (operationsLogger.isLoggable(Level.FINER)) {
411 operationsLogger.exiting(
412 GroupTxnManagerTransaction.class.getName(),
413 "modifyParticipant");
414 }
415
416 return;
417 }
418
419 ph.setPrepState(state);
420 if (operationsLogger.isLoggable(Level.FINER)) {
421 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
422 "modifyParticipant");
423 }
424 }
425
426
427
428
429
430
431
432
433
434
435 boolean modifyTxnState(int state) {
436 if (operationsLogger.isLoggable(Level.FINER)) {
437 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
438 "modifyTxnState", new Integer(state));
439 }
440 boolean result = false;
441 synchronized (stateLock) {
442 switch (state) {
443 case ACTIVE:
444 case VOTING:
445 case COMMITTED:
446 case ABORTED:
447 result = states[trstate][state];
448 break;
449
450 default:
451 throw new IllegalArgumentException("GroupTxnManagerTransaction: " +
452 "modifyTxnState: invalid state");
453 }
454
455 if (result)
456 trstate = state;
457 }
458 if (operationsLogger.isLoggable(Level.FINER)) {
459 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
460 "modifyTxnState", Boolean.valueOf(result));
461 }
462 return result;
463 }
464
465
466
467
468
469
470
471
472
473
474
475
476 public void
477 join(TransactionParticipant preparedPart, long crashCount)
478 throws CannotJoinException, CrashCountException, RemoteException
479 {
480 if (operationsLogger.isLoggable(Level.FINER)) {
481 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
482 "join", new Object[] {preparedPart, new Long(crashCount)});
483 }
484
485
486
487 if (getState() != ACTIVE)
488 throw new CannotJoinException("not active");
489
490 if ((getState() == ACTIVE) && (ensureCurrent() == false)) {
491 doAbort(0);
492 throw new CannotJoinException("Lease expired");
493 }
494
495
496
497 try {
498 ParticipantHandle ph =
499 new ParticipantHandle(preparedPart, crashCount);
500 ParticipantHandle phtmp = (ParticipantHandle)
501 ((parts.contains(ph))?
502 parts.get(parts.indexOf(ph)):
503 null);
504
505 if (transactionsLogger.isLoggable(Level.FINEST)) {
506 transactionsLogger.log(Level.FINEST,
507 "Retrieved ParticipantHandle: {0}", phtmp);
508 }
509 if (phtmp != null) {
510 long oldcount = phtmp.getCrashCount();
511 if (oldcount == crashCount) {
512 return;
513 } else {
514 throw new CrashCountException("GroupTxnManagerTransaction: " +
515 "join: old = " + oldcount +
516 " new = " + crashCount);
517 }
518 }
519
520 add(ph);
521
522 } catch (InternalManagerException ime) {
523 if (transactionsLogger.isLoggable(Level.SEVERE)) {
524 transactionsLogger.log(Level.SEVERE,
525 "TransactionParticipant unable to join", ime);
526 }
527 throw ime;
528 } catch (RemoteException re) {
529 if (transactionsLogger.isLoggable(Level.FINEST)) {
530 transactionsLogger.log(Level.FINEST,
531 "TransactionParticipant unable to be stored", re);
532 }
533 throw re;
534 }
535 if (operationsLogger.isLoggable(Level.FINER)) {
536 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
537 "join");
538 }
539 }
540
541
542
543
544
545
546
547
548
549
550
551 public int getState() {
552 if (operationsLogger.isLoggable(Level.FINER)) {
553 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
554 "getState");
555 }
556 synchronized (stateLock) {
557 if (operationsLogger.isLoggable(Level.FINER)) {
558 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
559 "getState", new Integer(trstate));
560 }
561 return trstate;
562 }
563 }
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590 void commit(long waitFor)
591 throws CannotCommitException, TimeoutExpiredException, RemoteException
592 {
593 if (log.isDebugEnabled())
594 log.debug("entering TMT.commit()");
595
596 if (operationsLogger.isLoggable(Level.FINER)) {
597 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
598 "commit", new Long(waitFor));
599 }
600 long starttime = System.currentTimeMillis();
601
602
603
604
605 if ((getState() == ACTIVE) && (ensureCurrent() == false)) {
606 doAbort(0);
607 throw new CannotCommitException("Lease expired");
608 }
609
610 if (getState() == ABORTED)
611 throw new CannotCommitException("attempt to commit " +
612 "ABORTED transaction");
613
614
615
616
617
618
619 Vector joinvec = parthandles();
620
621 if (joinvec == null) {
622 if (!modifyTxnState(VOTING))
623 throw new CannotCommitException("attempt to commit " +
624 "ABORTED transaction");
625
626 if (modifyTxnState(COMMITTED))
627 return;
628 else
629 throw new CannotCommitException("attempt to commit " +
630 "ABORTED transaction");
631 }
632
633 try {
634 Enumeration joined = joinvec.elements();
635 int numparts = joinvec.size();
636 ParticipantHandle[] phs = new ParticipantHandle[numparts];
637 joinvec.copyInto(phs);
638
639 long now = starttime;
640 long transpired = 0;
641 long remainder = 0;
642
643 ClientLog log = logmgr.logFor(str.id);
644
645 if (transactionsLogger.isLoggable(Level.FINEST)) {
646 transactionsLogger.log(Level.FINEST,
647 "{0} TransactionParticipants have joined",
648 new Integer(numparts));
649 }
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670 int oldstate = getState();
671 Integer result = new Integer(ABORTED);
672 Exception alternateException = null;
673
674
675
676
677
678
679
680
681
682
683
684
685 if (modifyTxnState(VOTING)) {
686
687 if (oldstate == ACTIVE)
688 log.write(new CommitRecord(phs));
689
690
691
692
693
694
695 synchronized (jobLock) {
696 if (job == null) {
697
698
699
700
701
702 job = new PrepareJob(str, threadpool, wm, log, phs);
703
704
705
706
707
708 job.scheduleTasks();
709 }
710 }
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730 synchronized (jobLock) {
731 if ((job instanceof PrepareJob) || (job instanceof PrepareAndCommitJob)) {
732 try {
733 if (job.isCompleted(Long.MAX_VALUE))
734 result = (Integer) job.computeResult();
735 } catch (JobNotStartedException jnse) {
736
737 result = new Integer(NOTCHANGED);
738 } catch (ResultNotReadyException rnre) {
739
740 } catch (JobException je) {
741
742 }
743 }
744 }
745
746 } else {
747
748
749
750 if (getState() == ABORTED)
751 throw new CannotCommitException("transaction ABORTED");
752
753
754
755
756
757
758 if (getState() == COMMITTED)
759 result = new Integer(COMMITTED);
760 }
761
762 if (transactionsLogger.isLoggable(Level.FINEST)) {
763 transactionsLogger.log(Level.FINEST, "Voting result: {0}", TxnConstants.getName(result
764 .intValue()));
765 }
766
767 switch (result.intValue()) {
768 case NOTCHANGED:
769 break;
770
771 case ABORTED:
772 now = System.currentTimeMillis();
773 transpired = now - starttime;
774 remainder = waitFor - transpired;
775
776 if (remainder >= 0)
777 doAbort(remainder);
778 else
779 doAbort(0);
780
781 throw new CannotCommitException("Unable to commit " + "transaction");
782
783 case PREPARED:
784
785
786
787
788
789 if (modifyTxnState(COMMITTED)) {
790
791
792
793 allParticipantsPrepared();
794
795
796
797 synchronized (jobLock) {
798 job = new CommitJob(str, threadpool, wm, log, phs);
799
800
801
802
803 job.scheduleTasks();
804 }
805 } else {
806 throw new CannotCommitException("attempt to commit " + "ABORTED transaction");
807 }
808
809
810
811
812 case COMMITTED:
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844 synchronized (jobLock) {
845
846
847
848
849
850 if (job instanceof PrepareAndCommitJob) {
851 if (!modifyTxnState(COMMITTED))
852 throw new CannotCommitException("transaction " + "ABORTED");
853 break;
854 }
855
856
857
858 if (job instanceof AbortJob)
859 throw new CannotCommitException("transaction " + "ABORTED");
860 }
861
862 if (getState() != COMMITTED)
863 throw new InternalManagerException("GroupTxnManagerTransaction: " + "commit: "
864 + job + " got bad state: " + TxnConstants.getName(result.intValue()));
865
866 now = System.currentTimeMillis();
867 transpired = now - starttime;
868
869 boolean committed = false;
870
871
872
873
874
875
876
877 try {
878 remainder = waitFor - transpired;
879
880 synchronized (jobLock) {
881
882 if (remainder <= 0 || !job.isCompleted(remainder)) {
883
884
885
886
887
888
889
890 settler.noteUnsettledTxn(str.id);
891
892 throw new TimeoutExpiredException("timeout expired", true);
893 } else {
894 result = (Integer) job.computeResult();
895
896
897
898
899
900 if (!backupsCommitted) {
901
902
903
904
905 allParticipantsCommitted();
906 backupsCommitted = true;
907 } else {
908
909
910 }
911
912 committed = true;
913 }
914 }
915 } catch (ResultNotReadyException rnre) {
916
917
918 } catch (JobNotStartedException jnse) {
919
920 } catch (JobException je) {
921
922 }
923
924 if (committed)
925 break;
926
927 default:
928 throw new InternalManagerException("GroupTxnManagerTransaction: " + "commit: " + job
929 + " got bad state: " + TxnConstants.getName(result.intValue()));
930 }
931
932
933
934
935 log.invalidate();
936 } catch (RuntimeException rte) {
937 if (transactionsLogger.isLoggable(Level.FINEST)) {
938 transactionsLogger.log(Level.FINEST, "Problem committing transaction", rte);
939 }
940 throw rte;
941 } catch (LogException le) {
942 if (transactionsLogger.isLoggable(Level.FINEST)) {
943 transactionsLogger.log(Level.FINEST, "Problem persisting transaction", le);
944 }
945 throw new CannotCommitException("Unable to log");
946 }
947 if (operationsLogger.isLoggable(Level.FINER)) {
948 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(), "commit");
949 }
950 }
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970 void abort(long waitFor)
971 throws CannotAbortException, TimeoutExpiredException
972 {
973 if (operationsLogger.isLoggable(Level.FINER)) {
974 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
975 "abort", new Long(waitFor));
976 }
977 long starttime = System.currentTimeMillis();
978
979
980
981
982
983
984
985
986 try {
987 Vector joinvec = parthandles();
988
989 if (joinvec == null) {
990 if (modifyTxnState(ABORTED))
991 return;
992 else
993 throw new
994 CannotAbortException("Transaction already COMMITTED");
995 }
996
997 Enumeration joined = joinvec.elements();
998 int numparts = joinvec.size();
999 ParticipantHandle[] phs = new ParticipantHandle[numparts];
1000 joinvec.copyInto(phs);
1001
1002 ClientLog log = logmgr.logFor(str.id);
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 if (modifyTxnState(ABORTED)) {
1017 log.write(new AbortRecord(phs));
1018
1019 synchronized (jobLock) {
1020 if (!(job instanceof AbortJob)) {
1021 if (job != null)
1022 job.stop();
1023 job = new AbortJob(str, threadpool, wm, log, phs);
1024 job.scheduleTasks();
1025 }
1026 }
1027 } else {
1028 throw new CannotAbortException("Transaction already COMMITTED");
1029 }
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041 long now = System.currentTimeMillis();
1042 long transpired = now - starttime;
1043
1044 Integer result = new Integer(ACTIVE);
1045 boolean aborted = false;
1046
1047 long remainder = waitFor - transpired;
1048
1049 try {
1050 synchronized (jobLock) {
1051 if (remainder<= 0 || !job.isCompleted(remainder)) {
1052 settler.noteUnsettledTxn(str.id);
1053 throw new TimeoutExpiredException(
1054 "timeout expired",false);
1055 } else {
1056 result = (Integer) job.computeResult();
1057 aborted = true;
1058 }
1059 }
1060 } catch (ResultNotReadyException rnre) {
1061
1062 } catch (JobNotStartedException jnse) {
1063
1064 } catch (JobException je) {
1065 settler.noteUnsettledTxn(str.id);
1066 throw new TimeoutExpiredException("timeout expired", false);
1067 }
1068
1069
1070 if (!aborted)
1071 throw new InternalManagerException("GroupTxnManagerTransaction: " +
1072 "abort: AbortJob got bad state: " +
1073 TxnConstants.getName(result.intValue()));
1074
1075 log.invalidate();
1076 } catch (RuntimeException rte) {
1077 if (transactionsLogger.isLoggable(Level.SEVERE)) {
1078 transactionsLogger.log(Level.SEVERE,
1079 "Problem aborting transaction",
1080 rte);
1081 }
1082 throw new InternalManagerException("GroupTxnManagerTransaction: " +
1083 "abort: fatal error");
1084 } catch (LogException le) {
1085 if (transactionsLogger.isLoggable(Level.FINEST)) {
1086 transactionsLogger.log(Level.FINEST,
1087 "Problem persisting transaction",
1088 le);
1089 }
1090 throw new CannotAbortException("Unable to log");
1091 }
1092 if (operationsLogger.isLoggable(Level.FINER)) {
1093 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1094 "abort");
1095 }
1096 }
1097
1098 public Transaction getTransaction() {
1099 if (operationsLogger.isLoggable(Level.FINER)) {
1100 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1101 "getTransaction");
1102 }
1103 if (operationsLogger.isLoggable(Level.FINER)) {
1104 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1105 "getTransaction", str);
1106 }
1107 return str;
1108 }
1109
1110 public long getExpiration() {
1111 if (operationsLogger.isLoggable(Level.FINER)) {
1112 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1113 "getExpiration");
1114 }
1115 synchronized (leaseLock) {
1116 if (operationsLogger.isLoggable(Level.FINER)) {
1117 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1118 "getExpiration", new Date(expires));
1119 }
1120 return expires;
1121 }
1122 }
1123
1124 public void setExpiration(long newExpiration) {
1125 if (operationsLogger.isLoggable(Level.FINER)) {
1126 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1127 "setExpiration", new Date(newExpiration));
1128 }
1129 synchronized (leaseLock) {
1130 expires = newExpiration;
1131 }
1132 if (operationsLogger.isLoggable(Level.FINER)) {
1133 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1134 "setExpiration");
1135 }
1136 }
1137
1138 public Uuid getCookie() {
1139 if (operationsLogger.isLoggable(Level.FINER)) {
1140 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1141 "getCookie");
1142 }
1143 if (operationsLogger.isLoggable(Level.FINER)) {
1144 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1145 "getCookie", uuid);
1146 }
1147 return uuid;
1148 }
1149
1150 private void doAbort(long timeout) {
1151 if (operationsLogger.isLoggable(Level.FINER)) {
1152 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1153 "doAbort", new Long(timeout));
1154 }
1155 try {
1156 str.abort(timeout);
1157 } catch (RemoteException re) {
1158
1159 if (transactionsLogger.isLoggable(Levels.HANDLED)) {
1160 transactionsLogger.log(Levels.HANDLED,
1161 "Trouble aborting transaction", re);
1162 }
1163 } catch (TimeoutExpiredException te) {
1164
1165
1166 if (transactionsLogger.isLoggable(Levels.HANDLED)) {
1167 transactionsLogger.log(Levels.HANDLED,
1168 "Trouble aborting transaction", te);
1169 }
1170 } catch (TransactionException bte) {
1171
1172
1173
1174 if (transactionsLogger.isLoggable(Levels.HANDLED)) {
1175 transactionsLogger.log(Levels.HANDLED,
1176 "Trouble aborting transaction", bte);
1177 }
1178 }
1179 if (operationsLogger.isLoggable(Level.FINER)) {
1180 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1181 "doAbort");
1182 }
1183
1184 }
1185
1186 synchronized boolean ensureCurrent() {
1187 if (operationsLogger.isLoggable(Level.FINER)) {
1188 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1189 "ensureCurrent");
1190 }
1191 long cur = System.currentTimeMillis();
1192 boolean result = false;
1193 long useby = getExpiration();
1194
1195 if (useby > cur)
1196 result = true;
1197 if (operationsLogger.isLoggable(Level.FINER)) {
1198 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1199 "ensureCurrent", Boolean.valueOf(result));
1200 }
1201 return result;
1202 }
1203
1204
1205 private Vector parthandles() {
1206 if (operationsLogger.isLoggable(Level.FINER)) {
1207 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1208 "parthandles");
1209 }
1210 if ( (parts == null ) || ( parts.size() == 0 ) )
1211 return null;
1212
1213 Vector vect = new Vector(parts);
1214
1215 if (transactionsLogger.isLoggable(Level.FINEST)) {
1216 transactionsLogger.log(Level.FINEST,
1217 "Retrieved {0} participants",
1218 new Integer(vect.size()));
1219 }
1220
1221 if (operationsLogger.isLoggable(Level.FINER)) {
1222 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1223 "parthandles");
1224 }
1225
1226 return vect;
1227 }
1228
1229 private String getParticipantInfo() {
1230 if (operationsLogger.isLoggable(Level.FINER)) {
1231 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1232 "getParticipantInfo");
1233 }
1234 if ( (parts == null ) || ( parts.size() == 0 ) )
1235 return "No participants";
1236
1237 if (transactionsLogger.isLoggable(Level.FINEST)) {
1238 transactionsLogger.log(Level.FINEST,
1239 "{0} participants joined", new Integer(parts.size()));
1240 }
1241 StringBuffer sb = new StringBuffer(parts.size() + " Participants: ");
1242 ParticipantHandle ph;
1243 for (int i=0; i < parts.size(); i++) {
1244 ph = (ParticipantHandle)parts.get(i);
1245 sb.append(
1246 "{" + i + ", "
1247 + ph.getPreParedParticipant().toString() + ", "
1248 + TxnConstants.getName(ph.getPrepState())
1249 + "} ");
1250 }
1251 if (operationsLogger.isLoggable(Level.FINER)) {
1252 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1253 "getParticipantInfo", sb.toString());
1254 }
1255
1256 return sb.toString();
1257 }
1258
1259 void restoreTransientState(ProxyPreparer preparer)
1260 throws RemoteException
1261 {
1262 if (operationsLogger.isLoggable(Level.FINER)) {
1263 operationsLogger.entering(GroupTxnManagerTransaction.class.getName(),
1264 "restoreTransientState");
1265 }
1266 if ( (parts == null ) || ( parts.size() == 0 ) )
1267 return;
1268
1269 ParticipantHandle[] handles = (ParticipantHandle[])
1270 parts.toArray(new ParticipantHandle[parts.size()]);
1271 for (int i=0; i < handles.length; i++) {
1272 handles[i].restoreTransientState(preparer);
1273 if (transactionsLogger.isLoggable(Level.FINEST)) {
1274 transactionsLogger.log(Level.FINEST,
1275 "Restored transient state for {0}",
1276 handles[i]);
1277 }
1278 }
1279
1280 if (operationsLogger.isLoggable(Level.FINER)) {
1281 operationsLogger.exiting(GroupTxnManagerTransaction.class.getName(),
1282 "restoreTransientState");
1283 }
1284 }
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 private void allParticipantsPrepared()
1295 {
1296 if (log.isDebugEnabled())
1297 log.debug("Distribute all-participants-prepares message to backups");
1298
1299 InternalPassiveGroupTransactionManager ipgtm = PassiveGroupMahalo.getIPGTM();
1300 if (ipgtm == null) {
1301 log.debug("ipgtm == null");
1302 System.exit(0);
1303 }
1304 try {
1305
1306 startprepare = System.nanoTime();
1307 ipgtm.transPrepared(this, id);
1308
1309 } catch (RemoteException e) {
1310 log.error("Could not distribute transaction commit to backups", e);
1311 e.printStackTrace();
1312 System.exit(0);
1313 } catch (Exception e) {
1314 log.error("Error trying to prepare backup replicas: ", e);
1315 System.exit(0);
1316 }
1317
1318 log.debug("OK - All transaction participants prepared");
1319 endprepare = System.nanoTime();
1320 }
1321
1322
1323
1324
1325 private void allParticipantsCommitted()
1326 {
1327 if (log.isDebugEnabled())
1328 log.debug("Distribute all-participants-committed message to backups");
1329
1330 InternalPassiveGroupTransactionManager ipgtm = PassiveGroupMahalo.getIPGTM();
1331
1332 try {
1333
1334 startcommit = System.nanoTime();
1335 ipgtm.transCommitted(id);
1336
1337 } catch (RemoteException e) {
1338 log.error("Could not distribute transaction commit to backups", e);
1339 } catch (UnknownTransactionException e) {
1340 log.error("Transaction backups did not know of transaction id: " + id, e);
1341 }
1342
1343 log.debug("OK - All transaction participants committed");
1344 endcommit = System.nanoTime();
1345 log.debug(((endprepare - startprepare)) / 1000000 + "\t"
1346 + ((endcommit - startcommit) / 1000000));
1347 }
1348
1349
1350 protected long getID() {
1351 return id;
1352 }
1353
1354
1355
1356
1357 protected void setLogManager(LogManager logmgr)
1358 {
1359 this.logmgr = logmgr;
1360 }
1361
1362
1363
1364
1365 protected void setTaskManager(TaskManager taskmgr)
1366 {
1367 this.threadpool = taskmgr;
1368 }
1369
1370
1371
1372
1373 protected void setWakeupManager(WakeupManager wakeupMgr)
1374 {
1375 this.wm = wakeupMgr;
1376 }
1377
1378
1379
1380
1381 protected void setSettler(TxnSettler settler)
1382 {
1383 this.settler = settler;
1384 }
1385
1386
1387
1388
1389 protected void setLocks()
1390 {
1391 leaseLock = new Object();
1392 jobLock = new Object();
1393 stateLock = new Object();
1394 }
1395
1396 }