public ParticipantStub(final String id, final boolean durable, final W3CEndpointReference twoPCParticipant) throws Exception { // id will be supplied as null during recovery in which case we can delay creation // of the coordinator until restore_state is called if (id != null) { coordinator = new CoordinatorEngine(id, durable, twoPCParticipant) ; } }
if (current == State.STATE_ACTIVE) changeState(State.STATE_ABORTING) ; changeState(State.STATE_PREPARED_SUCCESS) ; sendCommit() ; sendRollback(); } else { sendUnknownTransaction(map, arjunaContext) ; forget(); sendRollback() ; sendUnknownTransaction(map, arjunaContext) ;
/** * Handle the committed event. * @param committed The committed notification. * @param map The addressing context. * @param arjunaContext The arjuna context. * * None -> None (ignore) * Active -> Aborting (invalid state) * Preparing -> Aborting (invalid state) * PreparedSuccess -> PreparedSuccess (invalid state) * Committing -> Committing (forget) * Aborting -> Aborting (invalid state) */ public synchronized void committed(final Notification committed, final MAP map, final ArjunaContext arjunaContext) { final State current = state ; if (current == State.STATE_ACTIVE) { changeState(State.STATE_ABORTING) ; } else if ((current == State.STATE_PREPARING) || (current == State.STATE_COMMITTING)) { forget() ; } }
(current == State.STATE_PREPARED_SUCCESS)) changeState(State.STATE_ABORTING) ; (current == State.STATE_PREPARED_SUCCESS)) sendRollback() ; forget() ; waitForState(State.STATE_ABORTING, TransportTimer.getTransportTimeout()) ; forget();
TimerTask newTimerTask = createTimerTask(); synchronized (this) { ParticipantClient.getClient().sendPrepare(participant, createContext(), instanceIdentifier) ; scheduleTimer(newTimerTask); } else {
oos.packString(coordinator.getId()) ; oos.packBoolean(coordinator.isDurable()) ; State state = coordinator.getState(); final XMLStreamWriter writer = SoapUtils.getXMLStreamWriter(sw) ; StreamHelper.writeStartElement(writer, QNAME_TWO_PC_PARTICIPANT) ; String eprefText = coordinator.getParticipant().toString(); writer.writeCData(eprefText); StreamHelper.writeEndElement(writer, null, null) ;
if (current == State.STATE_ACTIVE) changeState(State.STATE_PREPARING) ; sendPrepare() ; waitForState(State.STATE_PREPARING, TransportTimer.getTransportTimeout()) ;
if (current == State.STATE_PREPARED_SUCCESS) changeState(State.STATE_COMMITTING) ; sendCommit() ; waitForState(State.STATE_COMMITTING, TransportTimer.getTransportTimeout()) ;
/** * Send the rollback message. * */ private void sendRollback() { try { ParticipantClient.getClient().sendRollback(participant, createContext(), instanceIdentifier) ; } catch (final Throwable th) { if (WSTLogger.logger.isTraceEnabled()) { WSTLogger.logger.tracev("Unexpecting exception while sending Rollback", th) ; } } }
/** * Forget the current coordinator. */ private void forget() { // first, change state to null to indicate that the participant has completed. changeState(null) ; // participants which have not been recovered from the log can be deactivated now. // participants which have been recovered are left for the recovery thread to deactivate. // this is because the recovery thread may have timed out waiting for a response to // the commit message and gone on to complete its scan and suspend. the next scan // will detect this activated participant and note that it has completed. if a crash // happens in between the recovery thread can safely recreate and reactivate the // participant and resend the commit since the commit/committed exchange is idempotent. if (!recovered) { CoordinatorProcessor.getProcessor().deactivateCoordinator(this) ; } }
/** * Handle the readOnly event. * @param readOnly The readOnly notification. * @param map The addressing context. * @param arjunaContext The arjuna context. * * None -> None (ignore) * Active -> Active (forget) * Preparing -> Preparing (forget) * PreparedSuccess -> PreparedSuccess (invalid state) * Committing -> Committing (invalid state) * Aborting -> Aborting (forget) */ public synchronized void readOnly(final Notification readOnly, final MAP map, final ArjunaContext arjunaContext) { final State current = state ; if ((current == State.STATE_ACTIVE) || (current == State.STATE_PREPARING) || (current == State.STATE_ABORTING)) { if (current != State.STATE_ABORTING) { this.readOnly = true ; } forget() ; } }
public void commit() throws WrongStateException, SystemException { /* * null - committed * Active - illegal state * Preparing - illegal state * Prepared - illegal state * PreparedSuccess - illegal state * Committing - no response * Aborting - illegal state */ final State state = coordinator.commit() ; if (state != null) { if (state == State.STATE_COMMITTING) { // typically means no response from the remote end. // throw a comm exception to distinguish this case from the // one where the remote end itself threw a SystemException. throw new SystemCommunicationException(); } else { throw new WrongStateException() ; } } }
TimerTask newTimerTask = createTimerTask(); synchronized (this) { ParticipantClient.getClient().sendCommit(participant, createContext(), instanceIdentifier) ; scheduleTimer(newTimerTask); } else {
oos.packString(coordinator.getId()) ; oos.packBoolean(coordinator.isDurable()) ; State state = coordinator.getState(); final XMLStreamWriter writer = SoapUtils.getXMLStreamWriter(sw) ; StreamHelper.writeStartElement(writer, QNAME_TWO_PC_PARTICIPANT) ; String eprefText = coordinator.getParticipant().toString(); writer.writeCData(eprefText); StreamHelper.writeEndElement(writer, null, null) ;
(current == State.STATE_PREPARED_SUCCESS)) changeState(State.STATE_ABORTING) ; (current == State.STATE_PREPARED_SUCCESS)) sendRollback() ; forget() ; waitForState(State.STATE_ABORTING, TransportTimer.getTransportTimeout()) ; forget();
if (current == State.STATE_ACTIVE) changeState(State.STATE_PREPARING) ; sendPrepare() ; waitForState(State.STATE_PREPARING, TransportTimer.getTransportTimeout()) ;
if (current == State.STATE_PREPARED_SUCCESS) changeState(State.STATE_COMMITTING) ; sendCommit() ; waitForState(State.STATE_COMMITTING, TransportTimer.getTransportTimeout()) ;
/** * Handle the aborted event. * @param aborted The aborted notification. * @param map The addressing context. * @param arjunaContext The arjuna context. * * None -> None (ignore) * Active -> Aborting (forget) * Preparing -> Aborting (forget) * PreparedSuccess -> PreparedSuccess (invalid state) * Committing -> Committing (invalid state) * Aborting -> Aborting (forget) */ public synchronized void aborted(final Notification aborted, final MAP map, final ArjunaContext arjunaContext) { final State current = state ; if (current == State.STATE_ACTIVE) { changeState(State.STATE_ABORTING) ; } else if ((current == State.STATE_PREPARING) || (current == State.STATE_ABORTING)) { forget() ; } }
/** * Send the rollback message. * */ private void sendRollback() { try { ParticipantClient.getClient().sendRollback(participant, createContext(), instanceIdentifier) ; } catch (final Throwable th) { if (WSTLogger.logger.isTraceEnabled()) { WSTLogger.logger.tracev("Unexpecting exception while sending Rollback", th) ; } } }
/** * Forget the current coordinator. */ private void forget() { // first, change state to null to indicate that the participant has completed. changeState(null) ; // participants which have not been recovered from the log can be deactivated now. // participants which have been recovered are left for the recovery thread to deactivate. // this is because the recovery thread may have timed out waiting for a response to // the commit message and gone on to complete its scan and suspend. the next scan // will detect this activated participant and note that it has completed. if a crash // happens in between the recovery thread can safely recreate and reactivate the // participant and resend the commit since the commit/committed exchange is idempotent. if (!recovered) { CoordinatorProcessor.getProcessor().deactivateCoordinator(this) ; } }