/** * Destroys the RecoveryCoordinatorImpl object. * * @param * @return * @see */ final synchronized void destroy() { 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 // RecoveryCoordinator 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 RecoveryCoordinator object anyway. POA rcPoa = null; if (poa == null) { rcPoa = Configuration.getPOA("RecoveryCoordinator" /*#Frozen*/); } else { rcPoa = poa; } if (thisRef == null) { rcPoa.deactivate_object(rcPoa.servant_to_id(this)); } else { rcPoa.deactivate_object(rcPoa.reference_to_id(thisRef)); thisRef = null; } } } catch (Exception exc) { _logger.log(Level.WARNING, "jts.object_destroy_error", "RecoveryCoordinator"); } // finalize(); globalTID = null; internalSeq = 0; }
/** * Returns the CORBA Object which represents this object. * * @param * @return The CORBA object. * @see */ final synchronized RecoveryCoordinator object() { if (thisRef == null) { if (poa == null) { poa = Configuration.getPOA("RecoveryCoordinator" /*#Frozen*/); recoverable = Configuration.isRecoverable(); } try { if (recoverable && globalTID != null) { // Create the object id from the global transaction // identifier and the internal sequence number. byte[] tidBytes = globalTID.toBytes(); byte[] id = new byte[tidBytes.length + 4]; System.arraycopy(tidBytes, 0, id, 4, tidBytes.length); id[0] = (byte) internalSeq; id[1] = (byte) (internalSeq >> 8); id[2] = (byte) (internalSeq >> 16); id[3] = (byte) (internalSeq >> 24); // Activate the object and create the reference. poa.activate_object_with_id(id, this); org.omg.CORBA.Object obj = poa.create_reference_with_id(id, RecoveryCoordinatorHelper.id()); thisRef = RecoveryCoordinatorHelper.narrow(obj); // thisRef = (RecoveryCoordinator) this; } else { poa.activate_object(this); org.omg.CORBA.Object obj = poa.servant_to_reference(this); thisRef = RecoveryCoordinatorHelper.narrow(obj); // thisRef = (RecoveryCoordinator)this; } } catch (Exception exc) { _logger.log(Level.SEVERE, "jts.create_recoverycoordinator_error"); String msg = LogFormatter.getLocalizedMessage(_logger, "jts.create_recoverycoordinator_error"); throw new org.omg.CORBA.INTERNAL(msg); } } return thisRef; }
// same as replay_completion(res) : added for delegated recovery support public Status replay_completion(Resource res, String logPath) throws NotPrepared { if (_logger.isLoggable(Level.FINE)) { _logger.logp( Level.FINE, "RecoveryCoordinatorImpl", "replay_completion()", "replay_completion on Resource:" + res); } Status result = Status.StatusRolledBack; CoordinatorImpl coord = DelegatedRecoveryManager.getCoordinator(globalTID, logPath); if (coord != null) { try { result = coord.get_status(); } catch (SystemException exc) { } } switch (result.value()) { /* * If the transaction is still active, raise the NotPrepared * exception. The Coordinator must be marked rollback-only at * this point because we cannot allow the transaction to * complete if a participant has failed. */ case Status._StatusActive: case Status._StatusMarkedRollback: try { coord.rollback_only(); } catch (Throwable exc) { } throw new NotPrepared(); /* * If the transaction is prepared, the caller must wait for the * Coordinator to tell it what to do, so return an unknown status, and * do nothing. Note that if this Coordinator is sitting waiting for * its superior, this could take a int time. */ case Status._StatusPrepared: result = Status.StatusUnknown; break; /* * If the transaction has been committed, the caller will receive * a commit. * * GDH If the transaction is commiting then we pass this on * to the caller. This state (added in OTS 1.1 means that * TopCoordinator.recover must now accept the COMMITTING state. */ case Status._StatusCommitting: // MODIFICATION (Ram Jeyaraman) commented out the code below, // since a StatusCommitting will be upgraded to Committed in // the subordinate. /* // (Ram Jeyaraman) let the subordinate wait, and allow the root // finish driving the commit. result = Status.StatusUnknown; */ break; case Status._StatusCommitted: break; case Status._StatusRolledBack: // If the transaction has been rolled back, and there is // no Coordinator for the transaction, we must invoke rollback // directly, as it will not be done otherwise. However for // proxies, this rollback cannot be done from this thread as // it would cause deadlock in the server requesting resync. if (coord == null) { if (!Configuration.getProxyChecker().isProxy(res)) { rollbackOrphan(res); } else { // We must pass a duplicate of the proxy to the // rollback thread because this proxy will be destroyed // when the replay_completion request returns // to the remote server. try { OrphanRollbackThread rollbackThread = new OrphanRollbackThread(this, (Resource) res._duplicate()); rollbackThread.start(); } catch (SystemException exc) { } } } break; /* * In any other situation, assume that the transaction has been rolled * back. As there is a Coordinator, it will direct the Resource to roll * back. */ default: result = Status.StatusRolledBack; } return result; }