CoordinatorTermpublic class CoordinatorTerm extends Object implements CompletionHandlerThe CoordinatorTerm interface provides operations that allow an
Terminator to direct completion of a transaction without any dependency
on the Coordinator interface. |
Fields Summary |
---|
private CoordinatorImpl | coordinator | private boolean | subtransaction | private boolean | aborted | private boolean | heuristicDamage | private boolean | completed | private boolean | completing | static Logger | _logger |
Constructors Summary |
---|
CoordinatorTerm()Default CoordinatorTerm constructor.
| CoordinatorTerm(CoordinatorImpl coord, boolean subtran)Normal constructor.
Sets up the CoordinatorTerm with the Coordinator reference so that the
CoordinatorTerm can find the Coordinator to pass on the two-phase commit
messages.
A flag is passed to indicate whether the CoordinatorTerm
represents a subtransaction.
// Set up the instance variables from the values passed.
coordinator = coord;
subtransaction = subtran;
// Inform the Coordinator that this is the object that normally terminates
// the transaction.
if( coordinator != null )
coordinator.setTerminator(this);
|
Methods Summary |
---|
void | commit(boolean promptReturn)Informs the object that the transaction is to be committed.
Uses a private interface to pass the Terminator's commit request on to the
Coordinator.
This operation does not check for outstanding requests, that is done by
the Current operations (when the client is using direct interaction we
cannot provide checked behavior).
Before telling the Coordinator to commit, it is informed that the
transaction is about to complete, and afterwards it is told that the
transaction has completed, with an indication of commit or rollback.
// BUGFIX(Ram J) (12/16/2000) This was previously set to true, which the
// caused commit_one_phase exceptions not to be reported.
boolean commit_one_phase_worked_ok = false;
// If the transaction that this object represents has already been rolled
// back, raise the TRANSACTION_ROLLEDBACK exception and return.
// If the transaction completed with heuristic damage, report that.
if( aborted ) {
throw new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO);
}
// If there is no Coordinator reference, raise an exception.
if( coordinator == null ) {
String msg = LogFormatter.getLocalizedMessage(_logger,
"jts.no_coordinator_available");
LogicErrorException exc =
new LogicErrorException(msg);
throw exc;
}
// Remember that it is us that have initiated the completion so that we can
// ignore the aborted operation if it happens subsequently.
completing = true;
// Determine the current Control object and Coordinator. Determine whether
// the current transaction is the same as that being committed.
ControlImpl current = CurrentTransaction.getCurrent();
ControlImpl establishedControl = null;
Coordinator currentCoord = null;
boolean sameCoordinator = false;
if( current != null )
try {
if (Configuration.isLocalFactory()) {
currentCoord = current.get_localCoordinator();
} else {
currentCoord = current.get_coordinator();
}
sameCoordinator = coordinator.is_same_transaction(currentCoord);
} catch( Unavailable exc ) {}
// We must ensure that there is a current transaction at this point if it is a
// top-level transaction because the Synchronization objects expect to have
// transaction context.
// If this CoordinatorTerm was created by a Factory, then this commit will
// not have context because the Terminator is not a transactional object.
if( !subtransaction ) {
try {
if( current == null ||
!sameCoordinator ) {
establishedControl = new ControlImpl(null,coordinator,
new GlobalTID(coordinator.getGlobalTID()),
new Long(coordinator.getLocalTID()));
CurrentTransaction.setCurrent(establishedControl,true);
}
} catch( Throwable exc ) {
}
// Tell the Coordinator that the transaction is about to complete.
try {
((TopCoordinator)coordinator).beforeCompletion();
}
// If the Coordinator raised an exception, return it to the caller.
catch( SystemException exc ) {
completing = false;
throw exc;
}
// If a temporary context was established, end it now.
finally {
if( establishedControl != null ) {
CurrentTransaction.endCurrent(true);
establishedControl.doFinalize();
}
}
}
// End the association of the current Control object with the current thread
// if it is the same transaction as the one being committed.
// This is done here rather than in Current because the before completion
// method must be invoked while the transaction is still active.
Status status = Status.StatusCommitted;
if( sameCoordinator )
CurrentTransaction.endCurrent(true);
// Now, process the actual 2PC
Throwable heuristicExc = null;
// GDH Now see if we can legally call commit one phase
// the commitOnePhase method will return false if this is
// not possible.
try {
commit_one_phase_worked_ok = coordinator.commitOnePhase();
} catch( Throwable exc ) {
if( exc instanceof HeuristicHazard ||
exc instanceof HeuristicMixed ) {
heuristicExc = exc;
} else if( exc instanceof TRANSACTION_ROLLEDBACK ) {
status = Status.StatusRolledBack;
} else if( exc instanceof INVALID_TRANSACTION ) {
// Why have we driven before completion before now?
throw (INVALID_TRANSACTION)exc;
} if (exc instanceof INTERNAL) {
// ADDED(Ram J) percolate any system exception
// back to the caller.
throw (INTERNAL) exc;
}else {
}
}
if( commit_one_phase_worked_ok ) {
// Then we have done the commit already above
// Set the status for the after completion call
// even though currently the parm is not used
// inside the call - it get's the state from transtate
// the status variable here is a local flag.
status = Status.StatusCommitted; // GDH COPDEF1 Added this for neatness
} else if (status != Status.StatusRolledBack) { // Added (Ram J) (12/06/2000)
// commit two phase now
// Get the prepare vote from the root Coordinator.
Vote prepareResult = Vote.VoteRollback;
try {
prepareResult = coordinator.prepare();
} catch( HeuristicHazard exc ) {
heuristicExc = exc;
} catch( HeuristicMixed exc ) {
heuristicExc = exc;
} catch( INVALID_TRANSACTION exc ) {
throw exc;
} catch( Throwable exc ) {
}
if( subtransaction ) {
// Depending on the prepare result, commit or abort the transaction.
if( prepareResult == Vote.VoteCommit )
try {
if(_logger.isLoggable(Level.FINE))
{
_logger.logp(Level.FINE,"CoordinatorTerm","commit()",
"Before invoking coordinator.commit() :"+"GTID is: "+
((TopCoordinator)coordinator).superInfo.globalTID.toString());
}
coordinator.commit();
} catch( NotPrepared exc ) {
prepareResult = Vote.VoteRollback;
}
if( prepareResult == Vote.VoteRollback ) {
if(_logger.isLoggable(Level.FINE))
{
_logger.logp(Level.FINE,"CoordinatorTerm","commit()",
"Before invoking coordinator.rollback :"+
"GTID is : "+
((TopCoordinator)coordinator).superInfo.globalTID.toString());
}
coordinator.rollback(true);
status = Status.StatusRolledBack;
}
}
// End of dealing with top-level transactions.
else {
// Depending on the prepare result, commit or abort the transaction.
//$ DO SOMETHING ABOUT PROMPT RETURN */
try {
if( prepareResult == Vote.VoteCommit )
try {
coordinator.commit();
} catch( NotPrepared exc ) {
prepareResult = Vote.VoteRollback;
}
if( prepareResult == Vote.VoteRollback && heuristicExc == null ) {
status = Status.StatusRolledBack; // GDH COPDEF1 Swapped these two lines
coordinator.rollback(true); // (not stricly necessary for problem fix)
}
} catch( Throwable exc ) {
if (exc instanceof HeuristicHazard ||
exc instanceof HeuristicMixed) {
heuristicExc = exc;
}
// ADDED(Ram J) percolate any system exception
// back to the caller.
if (exc instanceof INTERNAL) {
throw (INTERNAL) exc;
}
}
} // end else was top level txn
} // end else used two phase else
// Tell the Coordinator that the transaction has completed (top-level
// transactions only).
if( !subtransaction ) {
((TopCoordinator)coordinator).afterCompletion(status);
}
// Inform the Control object that the transaction has completed.
completed = true;
if( current != null && sameCoordinator )
current.setTranState(status);
// If a heuristic was thrown, throw the exception.
if( heuristicExc != null ) {
if( heuristicExc instanceof HeuristicMixed )
throw (HeuristicMixed)heuristicExc;
else
throw (HeuristicHazard)heuristicExc;
}
// If the transaction was rolled back, raise an exception.
if( status == Status.StatusRolledBack ) {
TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_YES);
throw exc;
}
| void | dump()Dumps the state of the object.
| void | rollback()Informs the object that the transaction is to be rolled back.
Uses a private interface to pass the Terminator's rollback request on to
the Coordinator.
// If the transaction that this object represents has already been rolled
// back, raise an exception. Note that we cannot raise a heuristic exception
// here as it is not in the OMG interface.
if( aborted ) {
TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO);
throw exc;
}
// If there is no Coordinator reference, raise an exception.
if( coordinator == null ) {
String msg = LogFormatter.getLocalizedMessage(_logger,
"jts.no_coordinator_available");
LogicErrorException exc =
new LogicErrorException(msg);
throw exc;
}
// Remember that it is us that have initiated the completion so that we can
// ignore the aborted operation if it happens subsequently.
Coordinator currentCoord = null;
ControlImpl current = null;
completing = true;
// End the association of the current Control object with the current thread
// if it is the same transaction as the one being committed.
try {
current = CurrentTransaction.getCurrent();
} catch( Throwable exc ) {}
if( current != null )
try {
if (Configuration.isLocalFactory()) {
currentCoord = current.get_localCoordinator();
} else {
currentCoord = current.get_coordinator();
}
if( coordinator.is_same_transaction(currentCoord) )
CurrentTransaction.endCurrent(true);
}
// If an exception was raised, it must be because the transaction that the
// current Control object represents was rolled back. In that case, always
// end the current thread association.
catch( Throwable exc ) {
CurrentTransaction.endCurrent(true);
}
// Rollback the transaction and inform synchronisation objects.
Throwable heuristicExc = null;
try {
coordinator.rollback(true);
}
catch (Throwable exc) {
if (exc instanceof HeuristicHazard ||
exc instanceof HeuristicMixed) {
heuristicExc = exc;
}
// ADDED (Ram J) percolate any system exception to the caller
if (exc instanceof INTERNAL) {
throw (INTERNAL) exc;
}
} finally {
if( !subtransaction )
((TopCoordinator)coordinator).afterCompletion(Status.StatusRolledBack);
}
// Inform the Control object that the transaction has completed.
completed = true;
if( current != null )
current.setTranState(Status.StatusRolledBack);
// If a heuristic was thrown, throw the exception.
if( heuristicExc != null ) {
if( heuristicExc instanceof HeuristicMixed )
throw (HeuristicMixed)heuristicExc;
else
throw (HeuristicHazard)heuristicExc;
}
// Otherwise return normally.
| public void | setCompleted(boolean aborted, boolean heuristicDamage)Informs the CoordinatorTerm object that the transaction it represents
has completed.
Flags indicate whether the transaction aborted, and
whether there was heuristic damage.
This operation is invoked by a Coordinator when it is rolled back,
potentially by a caller other than the CoordinatorTerm itself. In the
event that it is some other caller, the CoordinatorTerm object performs the
after rollback synchronisation, and remembers the fact that it has aborted
for later.
// If the transaction that this object represents has already been rolled
// back, or is being rolled back by this object, just return.
if( !completing ) {
// If there is no Coordinator reference, we cannot do anything. Note that
// CompletionHandler does not permit an exception through this method so we
// cannot throw one.
// Set the flags and distribute after completion operations for the
// transaction.
completed = true;
this.aborted = aborted;
this.heuristicDamage = heuristicDamage;
if( coordinator == null ) {
} else if( !subtransaction )
((TopCoordinator)coordinator).afterCompletion(Status.StatusRolledBack);
}
|
|