CoordinatorResourceImplpublic class CoordinatorResourceImpl extends CoordinatorResourcePOA implements CompletionHandlerThe CoordinatorResourceImpl interface provides operations that allow a
Coordinator to be represented among the registered Resources of a
superior Coordinator, without requiring that the Coordinator support the
Resource interface. |
Fields Summary |
---|
private static POA | poa | private static boolean | recoverable | private CoordinatorResource | thisRef | boolean | beingForcedThis flag may be set to indicate that the transaction is being forced. | private GlobalTID | globalTID | private boolean | subtransaction | private boolean | aborted | private boolean | heuristicDamage | private boolean | completed | private boolean | setAsTerminator | static Logger | _logger |
Constructors Summary |
---|
CoordinatorResourceImpl(GlobalTID globalTID, CoordinatorImpl coord, boolean subtran)Normal constructor.
Sets up the CoordinatorResourceImpl with the Coordinator reference and the
local transaction identifier so that the Resource can always find the
Coordinator to pass on the two-phase commit messages.
A flag is passed to indicate whether the CoordinatorResourceImpl represents
a subtransaction.
// Set up the instance variables to those values passed in.
subtransaction = subtran;
this.globalTID = globalTID;
// Inform the Coordinator that this is the object that normally terminates
// the transaction.
if( coord != null )
coord.setTerminator(this);
| CoordinatorResourceImpl(byte[] key)Creates the CoordinatorResourceImpl with the given key. This is done when
the CoordinatorResource object is recreated after the server has been
restarted.
// Get the global transaction identifier from the key.
globalTID = new GlobalTID(key);
// GDH
// Ensure that recovery has completed so that we can get the Coordinator.
// This is now delayed until the 2PC methods for normal resync and is
// done as part of the superinfo.reconst
// RecoveryManager.waitForRecovery();
// Check that the global transaction identifier represents a known transaction.
// If it does not, then throw the OBJECT_NOT_EXIST exception.
// CoordinatorImpl coord = RecoveryManager.getCoordinator(globalTID);
// if( coord == null )
// {
// OBJECT_NOT_EXIST exc = new OBJECT_NOT_EXIST();
// if( trc != null ) trc.event(EVT_THROW).data(exc).write();
// throw exc;
// }
// If the transaction is known, then inform the Coordinator that this is the
// terminator for it.
// else
// coord.setTerminator(this);
// Leave other members at the default values.
|
Methods Summary |
---|
public void | commit()Informs the object that the transaction is to be committed.
Passes the superior Coordinator's commit request on to the Coordinator that
registered the CoordinatorResourceImpl, using a private interface.
If the Coordinator does not raise any heuristic exception, the
CoordinatorResourceImpl destroys itself.
// If no global identifier has been set up, we can do nothing.
if( globalTID == null ) {
INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// Commit operations should only come in for top-level transactions.
if( subtransaction ) {
INTERNAL exc = new INTERNAL(MinorCode.TopForSub,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// If the transaction that this object represents has already been completed,
// raise a heuristic exception if necessary. This object must wait for a
// forget before destroying itself if it returns a heuristic exception.
if( completed ) {
if( aborted ) {
heuristicDamage = true;
HeuristicRollback exc = new HeuristicRollback();
throw exc;
} else if( heuristicDamage ) {
HeuristicMixed exc = new HeuristicMixed();
throw exc;
}
} else {
// Look up the Coordinator for the transaction.
// GDH: First of all make sure it has been recovered if necessary
if(_logger.isLoggable(Level.FINE))
{
_logger.logp(Level.FINE,"CoordinatorResourceImpl","commit()",
"Before invoking RecoveryManager.waitForRecovery():"+
"GTID is: "+ globalTID.toString());
}
RecoveryManager.waitForRecovery();
TopCoordinator coord = (TopCoordinator)RecoveryManager.getCoordinator(globalTID);
// If there is a Coordinator, lock it for the duration of this operation.
// Tell the Coordinator to commit.
// If the Coordinator throws HeuristicMixed or HeuristicHazard,
// allow them to percolate to the caller.
if( coord != null )
synchronized( coord ) {
// GDH:
// Make sure the coordinator knows we are it's terminator
// (this is done here in case we are in a recovery situation)
// (the operation has been moved from the constructor of the
// this object to here as the constructor is now called
// to early to ensure the coordinator is present in all
// cases
// GDH:
// If the transaction has completed at this point the
// makeSureSetAsTerminator method will be unable to
// set the coordinators terminator and will throw
// an object not exist exception: This is what we want in this case.
makeSureSetAsTerminator();
coord.commit();
}
}
// If and we are not being forced, we can destroy ourselves before returning.
// Otherwise, the TopCoordinator will have called setCompleted to set up
// the information we need should a subsequent commit or rollback request
// arrive.
if( !beingForced )
destroy();
| public void | commit_one_phase()Informs the object that the transaction is to be committed in one phase.
Passes the superior Coordinator's single-phase commit request on to the
Coordinator that registered the CoordinatorResourceImpl, using a private
interface.
The result from the Coordinator is returned to the caller. If the
Coordinator did not raise any heuristic exception, the CoordinatorResourceImpl
destroys itself.
boolean rolledBack;
// If no global_identifier has been set up, we can do nothing.
if( globalTID == null ) {
INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// Commit operations should only come in for top-level transactions.
if( subtransaction ) {
INTERNAL exc = new INTERNAL(MinorCode.TopForSub,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// If the transaction that this object represents has already been completed,
// raise an exception if necessary.
if( completed ) {
if( aborted ) {
TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_NO);
throw exc;
}
} else {
// Look up the Coordinator for the transaction.
// GDH: First of all make sure it has been recovered if necessary
if(_logger.isLoggable(Level.FINE))
{
_logger.logp(Level.FINE,"CoordinatorResourceImpl","commit_one_phase()",
"Before invoking RecoveryManager.waitForRecovery(): "+
"GTID is: " + globalTID.toString());
}
RecoveryManager.waitForRecovery();
TopCoordinator coord = (TopCoordinator)RecoveryManager.getCoordinator(globalTID);
// If there is a Coordinator, lock it for the duration of this operation.
// Tell the Coordinator to commit, by first doing a prepare.
// If the Coordinator throws HeuristicMixed or HeuristicHazard,
// allow them to percolate to the caller.
if( coord != null ) {
rolledBack = false;
synchronized( coord ) {
// GDH:
// Make sure the coordinator knows we are it's terminator
// (this is done here in case we are in a recovery situation)
// (the operation has been moved from the constructor of the
// this object to here as the constructor is now called
// to early to ensure the coordinator is present in all
// cases
makeSureSetAsTerminator();
// The prepare operation may throw the HeuristicHazard exception. In this case
// allow it to go back to the caller.
Vote vote = Vote.VoteRollback;
try {
vote = coord.prepare();
} catch( HeuristicMixed exc ) {
throw new HeuristicHazard();
}
try {
if( vote == Vote.VoteCommit )
coord.commit();
else if (vote == Vote.VoteRollback) {
// COMMENT (Ram J) 12/11/2000 The above if check
// for rollback was added to avoid throwing a
// rollback exception for readonly votes.
coord.rollback(true);
rolledBack = true;
}
} catch (Throwable exc) {
// ADDED(Ram J) percolate any system exception
// back to the caller.
if (exc instanceof INTERNAL) {
destroy();
throw (INTERNAL) exc;
}
}
}
} else {
// coord is null
// We could still find no coord that matched even after recovery
// If there is still no coord then the process failed between
// deleting the subordinate coordinator and the result being received
// in the superior. As all of the recoverable work occurred in this
// server or in its subordinate servers (we are in cop), from a data integrity point of
// view, it does not matter what result the CoordinatorResource returns
// to the superior. However, the superior may still have a client attached
// and it would look strange if the transaction actually rolled back and
// the TRANSACTION_ROLLEDBACK exception was not reported to the client.
// Therefore we jump through hoops to give the best answer as possible.
// By delaying the call to forget_superior until CoordinatorResource's
// destructor we ensure the Coordinator and the CoordinatorResource are
// deleted together (as much as is possible in the JAVA/CORBA environment) and
// this occurs after the response has been sent to the superior (because
// the ORB is holding a reference count to the CoordinatorResource).
// Therefore, the most likely reason for this to occur is that the
// Coordinator was timed out (and removed) just before the server
// terminated. In this case, the transaction rolled back, which is the
// response that will be returned.
rolledBack = true;
}
if( rolledBack ) {
destroy();
TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_YES);
throw exc;
}
}
// Self-destruct before returning.
destroy();
| public void | commit_subtransaction(Coordinator parent)Informs the object that the subtransaction is to be committed.
Passes the superior Coordinator's commit request on to the SubCoordinator
that registered the CoordinatorResourceImpl, using a private interface.
The result from the SubCoordinator is returned to the caller. The
CoordinatorResourceImpl destroys itself.
// If no global identifier has been set up, we can do nothing.
if( globalTID == null ) {
INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// Commit_subtransaction operations should only come in for subtransactions.
if( !subtransaction ) {
INTERNAL exc = new INTERNAL(MinorCode.SubForTop,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// If the transaction that this object represents has already been rolled
// back, raise the TRANSACTION_ROLLEDBACK exception.
if( completed ) {
if( aborted ) {
destroy();
TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_YES);
throw exc;
}
} else {
// Look up the Coordinator for the subtransaction.
SubCoordinator coord = (SubCoordinator)RecoveryManager.getCoordinator(globalTID);
// If there is a Coordinator, lock it for the duration of this operation.
// Tell the Coordinator to prepare then commit.
// Record then ignore any exceptions - we do not expect heuristics during
// subtransaction completion.
if( coord != null ) {
boolean rolledBack = false;
synchronized( coord ) {
try {
if( coord.prepare() == Vote.VoteCommit )
coord.commit();
else {
coord.rollback(true);
rolledBack = true;
}
}
catch( Throwable ex ) {
}
}
if( rolledBack ) {
destroy();
TRANSACTION_ROLLEDBACK exc = new TRANSACTION_ROLLEDBACK(0,CompletionStatus.COMPLETED_YES);
throw exc;
}
}
}
// Destroy ourselves before returning (there is no heuristic information for
// subtransactions).
destroy();
| void | destroy()Destroys the CoordinatorResourceImpl object.
try {
if (poa != null && thisRef != null) {
poa.deactivate_object(poa.reference_to_id(thisRef));
thisRef = null;
} else {
// BUGFIX(Ram J) It is possible that the
// CoordinatorResource object was activated via the activation
// daemon. In that case, there is no guarantee
// that poa and thisRef are set to a meaningful value.
// So, try to deactivate the CoordinatorResource object anyway.
POA crPoa = null;
if (poa == null) {
crPoa = Configuration.getPOA("CoordinatorResource"/*#Frozen*/);
} else {
crPoa = poa;
}
if (thisRef == null) {
crPoa.deactivate_object(crPoa.servant_to_id(this));
} else {
crPoa.deactivate_object(crPoa.reference_to_id(thisRef));
thisRef = null;
}
}
} catch( Exception exc ) {
_logger.log(Level.WARNING,"jts.object_destroy_error","CoordinatorResource");
}
// finalize();
globalTID = null;
| void | dump()Dumps the state of the object.
| public void | forget()Informs the object that the transaction is to be forgotten.
Informs the CoordinatorResourceImpl that it does not need to retain heuristic
information any longer.
// Forget operations should only come in for top-level transactions.
if( subtransaction ) {
INTERNAL exc = new INTERNAL(MinorCode.TopForSub,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// If no exception is raised, we can destroy ourselves before returning.
destroy();
| void | makeSureSetAsTerminator()Makes sure this object is set as the Coordinator Terminator
if( !setAsTerminator ) {
CoordinatorImpl coord = RecoveryManager.getCoordinator(globalTID);
// If the transaction is not known then throw an exception,
// otherwise inform the Coordinator that this is the
// terminator for it.
if( coord == null ) {
OBJECT_NOT_EXIST exc = new OBJECT_NOT_EXIST();
throw exc;
} else {
coord.setTerminator(this);
setAsTerminator = true;
}
}
| CoordinatorResource | object()Returns the CORBA Object which represents this object.
if( thisRef == null ) {
if( poa == null ) {
poa = Configuration.getPOA("CoordinatorResource"/*#Frozen*/);
recoverable = Configuration.isRecoverable();
}
try {
byte[] id = null;
if (recoverable && globalTID != null) {
id = globalTID.toBytes();
poa.activate_object_with_id(id, this);
org.omg.CORBA.Object obj = poa.create_reference_with_id(id, CoordinatorResourceHelper.id());
thisRef = CoordinatorResourceHelper.narrow(obj);
//thisRef = (CoordinatorResource) this;
} else {
poa.activate_object(this);
org.omg.CORBA.Object obj = poa.servant_to_reference(this);
thisRef = CoordinatorResourceHelper.narrow(obj);
//thisRef = (CoordinatorResource) this;
}
} catch( ServantAlreadyActive saexc ) {
_logger.log(Level.SEVERE,
"jts.create_CoordinatorResource_object_error",saexc);
String msg = LogFormatter.getLocalizedMessage(_logger,
"jts.create_CoordinatorResource_object_error");
throw new org.omg.CORBA.INTERNAL(msg);
} catch( ServantNotActive snexc ) {
_logger.log(Level.SEVERE,
"jts.create_CoordinatorResource_object_error",snexc);
String msg = LogFormatter.getLocalizedMessage(_logger,
"jts.create_CoordinatorResource_object_error");
throw new org.omg.CORBA.INTERNAL(msg);
} catch( Exception exc ) {
_logger.log(Level.SEVERE,
"jts.create_CoordinatorResource_object_error",exc);
String msg = LogFormatter.getLocalizedMessage(_logger,
"jts.create_CoordinatorResource_object_error");
throw new org.omg.CORBA.INTERNAL(msg);
}
}
return thisRef;
| public Vote | prepare()Requests the prepare phase vote from the object.
This uses a private interface to pass the superior Coordinator's prepare request.
on to the Coordinator that registered the CoordinatorResourceImpl.
The result from the Coordinator is returned to the caller.
Vote result = Vote.VoteRollback;
// If no global identifier has been set up, we can do nothing but vote for
// the transaction to be rolled back.
if( globalTID == null ) {
INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// Prepare operations should only come in for top-level transactions.
if( subtransaction ) {
INTERNAL exc = new INTERNAL(MinorCode.TopForSub,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// If the transaction that this object represents has already been rolled
// back, return a rollback vote.
if (completed) {
if (aborted) {
result = Vote.VoteRollback;
} else {
result = Vote.VoteCommit;
}
} else {
// Look up the Coordinator for the transaction.
TopCoordinator coord = (TopCoordinator)RecoveryManager.getCoordinator(globalTID);
// If there is a Coordinator, lock it for the duration of this operation.
// If there is no Coordinator, return a rollback vote.
if( coord != null )
synchronized( coord ) {
// Get the Coordinator's vote.
// If the Coordinator throws HeuristicMixed or HeuristicHazard,
// allow them to percolate to the caller.
result = coord.prepare();
// If the Coordinator has voted to roll the transaction back, then this
// CoordinatorResourceImpl will not be called again. Ensure that the
// Coordinator has rolled back.
// If the Coordinator throws HeuristicMixed or HeuristicHazard,
// allow them to percolate to the caller.
if( result == Vote.VoteRollback )
coord.rollback(false);
}
}
// If the Coordinator has voted to roll the transaction back, then this
// CoordinatorResourceImpl will not be called again.
// If a heuristic exception was thrown, this will be done in forget.
if (result == Vote.VoteRollback) {
destroy();
}
return result;
| public void | rollback()Informs the object that the transaction is to be rolled back.
Passes the superior Coordinator's rollback request on to the Coordinator
that registered the CoordinatorResourceImpl, using a private interface.
If the Coordinator does not raise any heuristic exception, the
CoordinatorResourceImpl destroys itself.
// If no global identifier has been set up, we can do nothing.
if( globalTID == null ) {
INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// Rollback operations should only come in for top-level transactions.
if( subtransaction ) {
INTERNAL exc = new INTERNAL(MinorCode.TopForSub,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// If the transaction that this object represents has already been completed,
// raise a heuristic exception if necessary. This object must wait for a
// forget before destroying itself if it returns a heuristic exception.
if( completed ) {
if( !aborted ) {
heuristicDamage = true;
HeuristicCommit exc = new HeuristicCommit();
throw exc;
}
else if( heuristicDamage ) {
HeuristicMixed exc = new HeuristicMixed();
throw exc;
}
} else {
// Look up the Coordinator for the transaction.
// GDH: First of all make sure it has been recovered if necessary
if(_logger.isLoggable(Level.FINE))
{
_logger.logp(Level.FINE,"CoordinatorResourceImpl","rollback()",
"Before invoking RecoveryManager.waitForRecovery(): "+
"GTID is : "+ globalTID.toString());
}
RecoveryManager.waitForRecovery();
TopCoordinator coord = (TopCoordinator)RecoveryManager.getCoordinator(globalTID);
// If there is a Coordinator, lock it for the duration of this operation.
// Tell the Coordinator to rollback.
// If the Coordinator throws HeuristicMixed or HeuristicHazard,
// allow them to percolate to the caller.
if( coord != null )
synchronized( coord ) {
// GDH:
// Make sure the coordinator knows we are it's terminator
// (this is done here in case we are in a recovery situation)
// (the operation has been moved from the constructor of the
// this object to here as the constructor is now called
// to early to ensure the coordinator is present in all
// cases
makeSureSetAsTerminator();
coord.rollback(true);
}
}
// If we are not being forced, we can destroy ourselves before returning.
// Otherwise, the TopCoordinator will have called set_completed to set up
// the information we need should a subsequent commit or rollback request
// arrive.
if( !beingForced )
destroy();
| public void | rollback_subtransaction()Informs the object that the subtransaction is to be rolled back.
Passes the superior Coordinator's rollback request on to the SubCoordinator
that registered the CoordinatorResourceImpl, using a private interface.
The result from the SubCoordinator is returned to the caller. The
CoordinatorResourceImpl destroys itself.
// If no global identifier has been set up, we can do nothing.
if( globalTID == null ) {
INTERNAL exc = new INTERNAL(MinorCode.NoGlobalTID,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// Commit_subtransaction operations should only come in for subtransactions.
if( !subtransaction ) {
INTERNAL exc = new INTERNAL(MinorCode.SubForTop,
CompletionStatus.COMPLETED_NO);
throw exc;
}
// If the transaction that this object represents has already been completed,
// do nothing.
if( !completed ) {
// Look up the Coordinator for the transaction.
SubCoordinator coord = (SubCoordinator)RecoveryManager.getCoordinator(globalTID);
// If there is a Coordinator, lock it for the duration of this operation.
// Tell the Coordinator to rollback.
if( coord != null )
synchronized( coord ) {
coord.rollback(true);
}
}
// Destroy ourselves before returning (there is no heuristic information for
// subtransactions).
destroy();
| public void | setCompleted(boolean aborted, boolean heuristicDamage)Informs the CoordinatorResourceImpl object that the transaction it
represents has completed.
Flags indicate whether the transaction aborted, and whether there was
heuristic damage.
// Record the information.
completed = true;
this.aborted = aborted;
this.heuristicDamage = heuristicDamage;
|
|