KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jts > CosTransactions > TransactionState


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * Copyright 2004-2005 Sun Microsystems, Inc. All rights reserved.
26  * Use is subject to license terms.
27  */

28
29 //----------------------------------------------------------------------------
30
//
31
// Module: TransactionState.java
32
//
33
// Description: Transaction state manager.
34
//
35
// Product: com.sun.jts.CosTransactions
36
//
37
// Author: Simon Holdsworth
38
//
39
// Date: March, 1997
40
//
41
// Copyright (c): 1995-1997 IBM Corp.
42
//
43
// The source code for this program is not published or otherwise divested
44
// of its trade secrets, irrespective of what has been deposited with the
45
// U.S. Copyright Office.
46
//
47
// This software contains confidential and proprietary information of
48
// IBM Corp.
49
//----------------------------------------------------------------------------
50

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 JavaDoc;
61 import java.util.logging.Level JavaDoc;
62 import com.sun.logging.LogDomains;
63 import com.sun.jts.utils.LogFormatter;
64 /**
65  * The TransactionState interface provides operations that maintain the
66  * relative commitment state of a Coordinator object, and is responsible for
67  * allocating new global and local transaction identifiers. This class is
68  * contained in the TopCoordinator and SubCoordinator classes.
69  *
70  * @version 0.7
71  *
72  * @author Simon Holdsworth, IBM Corporation
73  *
74  * @see
75  */

76
77 //----------------------------------------------------------------------------
78
// CHANGE HISTORY
79
//
80
// Version By Change Description
81
// 0.1 SAJH Initial implementation.
82
// 0.2 SAJH GlobalTID interface changes.
83
// 0.3 SAJH Repository synchronization.
84
// 0.4 SAJH Conversion to new bindings.
85
// 0.5 SAJH Modified log record writing.
86
// 0.6 SAJH Allow preparing->rolled back for prepare heuristics.
87
// 0.7 SAJH Renamed repository.
88
// 0.8 GDH Added commit_one_phase related states
89
//----------------------------------------------------------------------------
90

91 class TransactionState {
92
93     /**
94      * A state value indicating that the transaction has not yet been started.
95      */

96     final static int STATE_NONE = 0;
97
98     /**
99      * A state value indicating that the transaction has been started,
100      * and not yet completed.
101      */

102     final static int STATE_ACTIVE = 1;
103
104     /**
105      * A state value indicating that the transaction is in the process of being
106      * prepared.
107      */

108     final static int STATE_PREPARING = 2;
109
110     /**
111      * A state value indicating that the transaction has been
112      * successfully prepared, but commit or rollback has not yet started.
113      */

114     final static int STATE_PREPARED_SUCCESS = 3;
115
116     /**
117      * A state value indicating that the transaction has failed to be prepared,
118      * but rollback has not yet started.
119      */

120     final static int STATE_PREPARED_FAIL = 4;
121
122     /**
123      * A state value indicating that the transaction has been prepared
124      * and is read-only, but rollback has not yet started.
125      */

126     final static int STATE_PREPARED_READONLY = 5;
127
128     /**
129      * A state value indicating that the transaction is in the process of being
130      * committed.
131      */

132     final static int STATE_COMMITTING = 6;
133
134     /**
135      * A state value indicating that the transaction has been committed.
136      */

137     final static int STATE_COMMITTED = 7;
138
139     /**
140      * A state value indicating that the transaction is in the process of being
141      * rolled back.
142      */

143     final static int STATE_ROLLING_BACK = 8;
144
145     /**
146      * A state value indicating that the transaction has been rolled back.
147      */

148     final static int STATE_ROLLED_BACK = 9;
149
150     // GDH: New COP States
151
/**
152      * A state value indicating that the transaction is being commited
153      * to a downstream resource using one phase commit
154      */

155     final static int STATE_COMMITTING_ONE_PHASE = 10;
156
157
158     /**
159      * A state value indicating that the transaction has been successfully
160      * commited using commit one phase
161      */

162     final static int STATE_COMMITTED_ONE_PHASE_OK = 11;
163
164
165     /**
166      * A state value indicating that the transaction has been rolled back
167      * after a commit one phase flow.
168      */

169     final static int STATE_COMMIT_ONE_PHASE_ROLLED_BACK = 12;
170
171     /**
172      * A state value indicating that the transaction has heuristic
173      * hazard after a commit one phase flow.
174      */

175     final static int STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD = 13;
176
177     /**
178      * A state value indicating that the resources are heuristic mixed
179      * after a commit one phase flow.
180      */

181     final static int STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED = 14;
182
183     /*
184         Logger to log transaction messages
185     */

186     static Logger JavaDoc _logger = LogDomains.getLogger(LogDomains.TRANSACTION_LOGGER);
187
188     static RWLock freezeLock = new RWLock();
189     GlobalTID globalTID = null;
190     Long JavaDoc localTID = null;
191     int state = STATE_NONE;
192
193     boolean subordinate = false;
194     CoordinatorLog logRecord = null;
195     Object JavaDoc logSection = null;
196
197     //static long epochNumber = new Date().getTime();
198
static long sequenceNumber = 1;
199
200     static boolean inDoubt = false;
201
202     //get server name only once
203
//static String serverName = Configuration.getServerName();
204

205     //half built cached TID - used as template for any globalTIDs generations
206
static byte [] TIDTemplate=null;
207
208     // GDH State table added to for one phase commit of single resource
209
// could have extended further to split out:
210
// heuristic rollback
211
// rolling back huristic hazard
212
// rolling back heuristic mixed
213
// but these are factored into rolled back and rolling back respectively
214

215
216     // GDH: Added this column onwards
217
//
218
final static boolean[][] validStateChange = {
219     /* from to none actve ping pds pdf pdr cing cd ring rd c1p 1p_ok 1p_rb 1p_hh 1p_hm */
220     /* none */ { false, true, false, false, false, false, false, false, true, false, false, false, false, false, false },
221     /* active */ { false, false, true, false, false, false, false, false, true, false, true, false, false, false, false },
222     /* preparing */ { false, false, false, true, true, true, false, false, true, true, false, false, false, false, false },
223     /* prepared_success*/ { false, false, false, false, false, false, true, false, true, false, false, false, false, false, false },
224     /* prepared_fail */ { false, false, false, false, false, false, false, false, true, false, false, false, false, false, false },
225     /* prepared_ro */ { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false },
226     /* committing */ { false, false, false, false, false, false, true, true, false, false, false, false, false, false, false },
227     /* committed */ { true, false, false, false, false, false, false, false, false, false, false, false, false, false, false },
228     /* rolling back */ { false, false, false, false, false, false, false, false, true, true, false, false, false, false, false },
229     /* rolled back */ { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false },
230     // GDH: Added this row onwards
231
/* commit_one_phas */ { false, false, false, false , false, false, false, false, true, false, true, true, true, true, true },
232     /* cmt_one_phse_ok */ { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false },
233     /* cmt_one_phse_rb */ { false, false, false, false, false, false, false, false, false, true, false, false, false, false, false },
234     /* cmt_one_phse_hh */ { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false },
235     /* cmt_one_phse_hm */ { false, false, false, false, false, false, false, true, false, false, false, false, false, false, false }};
236
237     // XID format identifier.
238

239     final static int XID_FORMAT_ID = ('J'<<16) + ('T'<<8) + 'S';
240
241     private final static String JavaDoc LOG_SECTION_NAME = "TS"/*#Frozen*/;
242
243     /**
244      * Default TransactionState constructor.
245      *
246      * @param
247      *
248      * @return
249      *
250      * @see
251      */

252     TransactionState() {}
253
254     /**
255      * This constructor is used for a root Coordinator.
256      * It allocates a global identifier for the transaction, and a local
257      * identifier for the local Transaction Service. The global ID is used to
258      * propagate to other processes to identify the transaction globally. The
259      * local ID is used for local comparisons. The CoordinatorLog object is
260      * used to recover the TransactionState at restart. Use of this operation
261      * indicates that the transaction is a top-level transaction. A section is
262      * created in the given CoordinatorLog object to maintain the transaction
263      * state persistently.
264      *
265      * @param log The CoordinatorLog object for the transaction.
266      *
267      * @return
268      *
269      * @see
270      */

271     TransactionState(CoordinatorLog log) {
272
273         // Get the sequence number for the transaction identifier.
274

275         localTID = new Long JavaDoc(getSequenceNumber());
276
277         // Get the epoch number for this execution of the server.
278

279         //int epoch = getEpochNumber();
280

281         // Create a global identifier.
282

283         globalTID = new GlobalTID(XID_FORMAT_ID, 0,
284                                   generateTID(localTID.longValue()));
285
286         // Store the values in instance variables.
287
// This is a top-level transaction.
288

289         state = STATE_NONE;
290         subordinate = false;
291
292         // Set the CoordinatorLog id to the InternalTid.
293

294         if (log != null) {
295             logRecord = log;
296             logRecord.setLocalTID(localTID);
297
298             // Create a section in the CoordinatorLog for TransactionState
299

300             logSection = logRecord.createSection(LOG_SECTION_NAME);
301         }
302     }
303
304     /**
305      * This constructor is used for a subordinate Coordinator.
306      * It allocates a local identifier for a subordinate transaction that is
307      * represented by the given global identifier, and returns it.
308      * The presence of a CoordinatorLog object indicates
309      * whether the transaction is a top-level
310      * transaction. A section is created in the given CoordinatorLog object to
311      * maintain the transaction state persistently.
312      *
313      * @param globalTID The global identifier for the transaction.
314      * @param log The CoordinatorLog for a top-level transaction.
315      *
316      * @return
317      *
318      * @see
319      */

320     TransactionState(GlobalTID globalTID, CoordinatorLog log) {
321
322         // Get the sequence number for the transaction identifier.
323

324         this.globalTID = globalTID;
325         localTID = new Long JavaDoc(getSequenceNumber());
326
327         // Store the values in instance variables.
328

329         state = STATE_NONE;
330         subordinate = true;
331
332         // Create a section in the CoordinatorLog.
333

334         if (log != null) {
335             logRecord = log;
336
337             // Set the CoordinatorLog id to the InternalTid.
338

339             logRecord.setLocalTID(localTID);
340
341             // Create a section in the CoordinatorLog for TransactionState
342

343             logSection = logRecord.createSection(LOG_SECTION_NAME);
344         }
345     }
346
347     /**
348      * This constructor is used for a root nested transaction.
349      * It allocates a global identifier and local identifier
350      * for a child transaction based on the local
351      * and global identifiers given for the parent, and returns
352      * them. The use of this operation indicates that the transaction is a
353      * subtransaction.
354      *
355      * @param parentLocalTID The parent's local identifier.
356      * @param parentGlobalTID The parent's global identifier.
357      *
358      * @return
359      *
360      * @see
361      */

362     TransactionState(Long JavaDoc parentLocalTID, GlobalTID parentGlobalTID) {
363
364         // Get the sequence number for the transaction identifier.
365

366         localTID = new Long JavaDoc(getSequenceNumber());
367
368         // Get the epoch number for this execution of the server.
369

370         //int epoch = getEpochNumber();
371

372         // Create a global identifier.
373

374         globalTID = new GlobalTID(XID_FORMAT_ID, 0,
375                                   generateTID(localTID.longValue()));
376
377         // Store the values in instance variables. This is a subtransaction.
378

379         state = STATE_NONE;
380         subordinate = false;
381     }
382
383     /**
384      * Directs the TransactionState to recover its state
385      * after a failure, based on the given CoordinatorLog object.
386      * If the TransactionState has already been defined or
387      * recovered, the operation returns the current state of the transaction.
388      * If the state cannot be recovered, the operation returns none.
389      * If the CoordinatorLog records information prior to a log record being
390      * forced, this may result in recovery of an in-flight transaction. The
391      * TransactionState returns active in this case.
392      *
393      * @param log The CoordinatorLog for the transaction.
394      *
395      * @return The current state of the transaction.
396      *
397      * @see
398      */

399     int reconstruct(CoordinatorLog log) {
400
401         int result = STATE_NONE;
402
403         // Get a section id in the CoordinatorLog for TransactionState
404

405         logSection = log.createSection(LOG_SECTION_NAME);
406         byte[][] logData = log.getData(logSection);
407
408         // Go through the sequence to get the overall status
409

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                 // If the log record data is invalid, then exit immediately.
417
_logger.log(Level.SEVERE,"jts.invalid_log_record_data",
418                         LOG_SECTION_NAME);
419                 String JavaDoc msg = LogFormatter.getLocalizedMessage(_logger,
420                             "jts.invalid_log_record_data",
421                             new java.lang.Object JavaDoc[] { LOG_SECTION_NAME });
422                 throw new org.omg.CORBA.INTERNAL JavaDoc(msg);
423             }
424         }
425
426         // Set the state value returned from the reconstruct method
427

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         // GDH new states-->
443
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     /**
464      * Cleans up the state of the object.
465      *
466      * @param
467      *
468      * @return
469      *
470      * @see
471      */

472     public void finalize() {
473
474         state = STATE_NONE;
475         globalTID = null;
476         localTID = null;
477         logRecord = null;
478         logSection = null;
479     }
480
481     /**
482      * Sets the state to the given value and returns true.
483      * If the state change is invalid, the state is not
484      * changed and the operation returns false. When a top-level
485      * transaction has its state changed to prepared, the information
486      * is stored in the CoordinatorLog object. When prepared_success, the log
487      * record for the transaction is explicitly forced. Otherwise the
488      * transaction will be treated as in-flight upon
489      * recovery (i.e. will be rolled back). When
490      * a subordinate transaction has its state changed to committing or
491      * rolling_back, the state is added to the CoordinatorLog object, which is
492      * then forced.
493      *
494      * @param newState The new state of the transaction.
495      *
496      * @return Indicates if the state change is possible.
497      *
498      * @see
499      */

500     boolean setState(int newState) {
501
502         boolean result = false;
503
504         // Check that the state change is valid
505

506         if (validStateChange[state][newState]) {
507
508             //Added code for counting and blocking.
509
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                     /*
526             case STATE_COMMITTED_ONE_PHASE_OK :
527                         AdminUtil.incrementCommitedTransactionCount();
528                         break ;
529                     case STATE_COMMIT_ONE_PHASE_ROLLED_BACK :
530                         AdminUtil.incrementCommitedTransactionCount();
531                         break ;
532             */

533             case STATE_ROLLING_BACK :
534                         AdminUtil.incrementUnpreparedAbortedTransactionCount();
535                         break;
536                 }
537             }
538
539
540             //release the readlocks.
541
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 JavaDoc 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 JavaDoc 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             //acquire read locks
592
switch ( newState )
593             {
594                 case STATE_PREPARING :
595                 case STATE_COMMITTING :
596                 //case STATE_ROLLING_BACK :
597
case STATE_COMMITTING_ONE_PHASE :
598                     if(_logger.isLoggable(Level.FINEST)){
599                         String JavaDoc 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 JavaDoc 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             // RecoveryHook (for induced crashes and waits) (Ram Jeyaraman)
641
if (FailureInducer.isFailureInducerActive() &&
642                     (!(Thread.currentThread().getName().
643                         equals("JTS Resync Thread"/*#Frozen*/)))) {
644                 Integer JavaDoc 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             // Change state. This is the point at which some
682
// log records may be written
683

684             state = newState;
685             result = true;
686
687             // Add state information to CoordinatorLog for various states.
688

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                      // GDH
697
// newState == STATE_COMMITTING_ONE_PHASE ||
698
// newState == STATE_COMMITTED_ONE_PHASE_OK ||
699
// newState == STATE_COMMIT_ONE_PHASE_ROLLED_BACK ||
700
newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD ||
701                      newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED
702                      // GDH
703
)) {
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             // If the new state represents successful preparation,
711
// and the transaction is a top-level transaction,
712
// or the new state indicates the beginning of commit or
713
// rollback and the Coordinator is a subordinate, we want to make
714
// sure that the log information is permanent.
715

716             if (logRecord != null &&
717                     (newState == STATE_PREPARED_SUCCESS ||
718                      // GDH: All the new states should be flushed to the log
719
// cop as it represents begining of commit and
720
// the others as they represent end of phase one
721
// (at least)
722

723                      newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_HAZARD ||
724                      newState == STATE_COMMIT_ONE_PHASE_HEURISTIC_MIXED ||
725                      // \GDH
726
(newState == STATE_COMMITTING && subordinate) ||
727                      (newState == STATE_ROLLING_BACK && subordinate))) {
728
729                 // If this is the first time a transaction has
730
// gone in-doubt in this process, then ensure
731
// that the restart required flag is set in the repository.
732

733                 setInDoubt(true);
734
735                 // Force the log record for the transaction.
736
// How much 'force' can we use in Java?
737

738                 if (!(result = logRecord.write(true))) {
739                     // empty
740
}
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                      // LogDBHelper.getInstance().addRecord(localTID.longValue(), globalTID.toTidBytes());
749
}
750             }
751                
752
753             // If the new state represents completion of a
754
// top-level transaction, a top-level transaction,
755
// then write an unforced record to the log.
756

757             if (logRecord != null && (newState == STATE_COMMITTED ||
758                                       // newState == STATE_COMMITTING_ONE_PHASE ||
759
// newState == STATE_COMMITTED_ONE_PHASE_OK ||
760
// newState == STATE_COMMIT_ONE_PHASE_ROLLED_BACK ||
761
newState == STATE_ROLLED_BACK)) {
762
763                 // Write the log record for the transaction (unforced).
764

765                 if (!(result = logRecord.write(false))) {
766                     // empty
767
}
768             }
769
770             // RecoveryHook (for induced crashes and waits) (Ram Jeyaraman)
771
if (FailureInducer.isFailureInducerActive() &&
772                     (!(Thread.currentThread().getName().
773                         equals("JTS Resync Thread"/*#Frozen*/)))) {
774                 Integer JavaDoc 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     /**
791      * Returns the current transaction sequence number and increments it.
792      *
793      * @param
794      *
795      * @return The current transaction sequence number.
796      *
797      * @see
798      */

799     private static synchronized long getSequenceNumber() {
800
801         return ++sequenceNumber;
802     }
803
804     /**
805      * Returns the current epoch number.
806      *
807      * @param
808      *
809      * @return The current epoch number.
810      *
811      * @see
812      */

813     /*private static int getEpochNumber() {
814
815     
816         int result = (int)epochNumber;
817         return result;
818     }*/

819
820     /**
821      * Returns a flag indicating whether any transactions may be in doubt.
822      *
823      * @param
824      *
825      * @return The in doubt indicator.
826      *
827      * @see
828      */

829     static boolean inDoubt() {
830         return inDoubt;
831     }
832
833     /**
834      * Sets the in doubt indicator.
835      *
836      * @param value The new value of the indicator.
837      *
838      * @return
839      *
840      * @see
841      */

842     static void setInDoubt(boolean value) {
843         inDoubt = value;
844     }
845
846     /**
847      * Generates the body of a transaction identifier.
848      *
849      * @param localTID The local transaction identifier.
850      * @param epoch The epoch number.
851      * @param serverName The server name.
852      *
853      * @return
854      *
855      * @see
856      */

857     private static final byte[] generateTID(long localTID) {
858         if(TIDTemplate==null){
859         synchronized(TransactionState.class){
860                 if(TIDTemplate==null){
861                     String JavaDoc 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