[jboss-svn-commits] JBL Code SVN: r21343 - in labs/jbosstm/trunk/XTS: WS-T/dev/src10/com/arjuna/wst/messaging/engines and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Aug 4 11:51:05 EDT 2008
Author: adinn
Date: 2008-08-04 11:51:05 -0400 (Mon, 04 Aug 2008)
New Revision: 21343
Modified:
labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryRecord.java
labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/messaging/engines/CoordinatorEngine.java
labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/stub/ParticipantStub.java
labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorEngine.java
labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/ParticipantStub.java
labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java
labs/jbosstm/trunk/XTS/WSTX/classes/com/arjuna/mwlabs/wst/at/participants/DurableTwoPhaseCommitParticipant.java
Log:
patches to recovery code to fix errors in handling of comms timeouts on coordinator side during prepare and commit identified by WSTF interop tests - part fix for JBTM-121
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryRecord.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryRecord.java 2008-08-04 15:35:11 UTC (rev 21342)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryRecord.java 2008-08-04 15:51:05 UTC (rev 21343)
@@ -47,23 +47,30 @@
try {
useSerialization = ATParticipantHelper.isSerializable(participant);
recoveryState = ATParticipantHelper.getRecoveryState(useSerialization, participant);
+ recoveryStateValid = true;
} catch (Exception exception) {
if (WSTLogger.arjLoggerI18N.isWarnEnabled())
{
WSTLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryRecord.saveState_1", new Object[] {id}) ;
}
- return false;
+ // if we continue here then we cannot recover this transaction if we crash during
+ // commit processing. we should strictly fail here to play safe but . . .
+
+ recoveryStateValid = false;
}
try {
oos.packString(id);
saveEndpointReference(oos);
+ oos.packBoolean(recoveryStateValid);
+ if (recoveryStateValid) {
oos.packBoolean(useSerialization);
- if (recoveryState != null) {
- oos.packBoolean(true);
- oos.packBytes(recoveryState);
- } else {
- oos.packBoolean(false);
+ if (recoveryState != null) {
+ oos.packBoolean(true);
+ oos.packBytes(recoveryState);
+ } else {
+ oos.packBoolean(false);
+ }
}
} catch (XMLStreamException xmle) {
if (WSTLogger.arjLoggerI18N.isWarnEnabled())
@@ -95,13 +102,15 @@
try {
id = ios.unpackString();
restoreEndpointReference(ios);
- useSerialization = ios.unpackBoolean();
- if (ios.unpackBoolean()) {
- recoveryState = ios.unpackBytes();
- } else {
- recoveryState = null;
+ recoveryStateValid = ios.unpackBoolean();
+ if (recoveryStateValid) {
+ useSerialization = ios.unpackBoolean();
+ if (ios.unpackBoolean()) {
+ recoveryState = ios.unpackBytes();
+ } else {
+ recoveryState = null;
+ }
}
- recoveryStateValid = true;
} catch (XMLStreamException xmle) {
if (WSTLogger.arjLoggerI18N.isWarnEnabled())
{
@@ -124,6 +133,7 @@
* specific recovery state back into a participant
* @param module the XTS recovery module to be used to attempt the conversion
* @return
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryRecord.restoreParticipant_1 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryRecord.restoreParticipant_1] participant {0} has no saved recovery state to recover
*/
public boolean restoreParticipant(XTSATRecoveryModule module) throws Exception
@@ -133,19 +143,28 @@
return false;
}
- if (useSerialization) {
- final ByteArrayInputStream bais = new ByteArrayInputStream(recoveryState) ;
- final ObjectInputStream ois = new ObjectInputStream(bais) ;
+ if (recoveryStateValid) {
+ if (useSerialization) {
+ final ByteArrayInputStream bais = new ByteArrayInputStream(recoveryState) ;
+ final ObjectInputStream ois = new ObjectInputStream(bais) ;
- participant = module.deserialize(getId(), ois);
+ participant = module.deserialize(getId(), ois);
+ } else {
+ participant = module.recreate(getId(), recoveryState);
+ }
+
+ if (participant != null) {
+ return true;
+ }
} else {
- participant = module.recreate(getId(), recoveryState);
- }
+ // the original participant did not provide a way to save its state so
+ // throw an exception to notify this
- if (participant != null) {
- return true;
+ String mesg = WSTLogger.arjLoggerI18N.getString("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryRecord.restoreParticipant_1", id);
+
+ throw new Exception(mesg);
}
-
+
return false;
}
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/messaging/engines/CoordinatorEngine.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/messaging/engines/CoordinatorEngine.java 2008-08-04 15:35:11 UTC (rev 21342)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/messaging/engines/CoordinatorEngine.java 2008-08-04 15:51:05 UTC (rev 21343)
@@ -346,13 +346,9 @@
timerTask = null;
}
- // ok, the coordinator is going to start a rollback because of this timeout but it will
- // only roll back the participants which have been prepared or have not yet been processed.
- // we need to deactivate the participant here so that any later prepared messages are
- // answered with a rollback (presumed abort)
+ // ok, we leave the participant stub active because the coordinator will attempt
+ // to roll it back when it notices that this has failed
- CoordinatorProcessor.getProcessor().deactivateCoordinator(this);
-
return state ;
}
}
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/stub/ParticipantStub.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/stub/ParticipantStub.java 2008-08-04 15:35:11 UTC (rev 21342)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src10/com/arjuna/wst/stub/ParticipantStub.java 2008-08-04 15:51:05 UTC (rev 21343)
@@ -103,7 +103,11 @@
}
else if (state == State.STATE_PREPARING)
{
- throw new SystemException() ;
+ // 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
{
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorEngine.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorEngine.java 2008-08-04 15:35:11 UTC (rev 21342)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorEngine.java 2008-08-04 15:51:05 UTC (rev 21343)
@@ -288,13 +288,9 @@
timerTask = null;
}
- // ok, the coordinator is going to start a rollback because of this timeout but it will
- // only roll back the participants which have been prepared or have not yet been processed.
- // we need to deactivate the participant here so that any later prepared messages are
- // answered with a rollback (presumed abort)
+ // ok, we leave the participant stub active because the coordinator will attempt
+ // to roll it back when it notices that this has failed
- CoordinatorProcessor.getProcessor().deactivateCoordinator(this);
-
return state ;
}
}
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/ParticipantStub.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/ParticipantStub.java 2008-08-04 15:35:11 UTC (rev 21342)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/ParticipantStub.java 2008-08-04 15:51:05 UTC (rev 21343)
@@ -70,7 +70,11 @@
}
else if (state == State.STATE_PREPARING)
{
- throw new SystemException() ;
+ // 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
{
@@ -124,7 +128,7 @@
{
if (state == State.STATE_ABORTING)
{
- throw new SystemException() ;
+ throw new SystemCommunicationException() ;
}
else
{
Modified: labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java 2008-08-04 15:35:11 UTC (rev 21342)
+++ labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/ParticipantRecord.java 2008-08-04 15:51:05 UTC (rev 21343)
@@ -421,6 +421,12 @@
{
return TwoPhaseOutcome.HEURISTIC_MIXED;
}
+ catch(SystemCommunicationException ex)
+ {
+ // if prepare timed out then we return error so it goes back on the
+ // prepare list and is rolled back
+ return TwoPhaseOutcome.FINISH_ERROR;
+ }
catch (SystemException ex)
{
return TwoPhaseOutcome.HEURISTIC_HAZARD;
Modified: labs/jbosstm/trunk/XTS/WSTX/classes/com/arjuna/mwlabs/wst/at/participants/DurableTwoPhaseCommitParticipant.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSTX/classes/com/arjuna/mwlabs/wst/at/participants/DurableTwoPhaseCommitParticipant.java 2008-08-04 15:35:11 UTC (rev 21342)
+++ labs/jbosstm/trunk/XTS/WSTX/classes/com/arjuna/mwlabs/wst/at/participants/DurableTwoPhaseCommitParticipant.java 2008-08-04 15:51:05 UTC (rev 21343)
@@ -44,6 +44,7 @@
import com.arjuna.mw.wsas.exceptions.SystemException;
import com.arjuna.mw.wsas.exceptions.WrongStateException;
import com.arjuna.mw.wsas.exceptions.SystemCommunicationException;
+import com.arjuna.mw.wstx.logging.wstxLogger;
import com.arjuna.mwlabs.wst.util.PersistableParticipantHelper;
/**
@@ -65,7 +66,14 @@
_id = identifier;
}
- public Vote prepare () throws InvalidParticipantException,
+ /**
+ * tell the participant to prepare
+ *
+ * @return the participant's vote or a cancel vote the aprticipant is null
+ *
+ * @message com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.prepare_1 [com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.prepare_1] comms timeout attempting to prepare WS-AT participant {0}
+ */
+ public Vote prepare () throws InvalidParticipantException,
WrongStateException, HeuristicHazardException,
HeuristicMixedException, SystemException
{
@@ -110,11 +118,25 @@
// catch (com.arjuna.mw.wst.exceptions.SystemException ex)
catch (com.arjuna.wst.SystemException ex)
{
+ if(ex instanceof com.arjuna.wst.stub.SystemCommunicationException) {
+ // log an error here or else the participant may be left hanging
+ // waiting for a prepare
+ if (wstxLogger.arjLoggerI18N.isErrorEnabled()) {
+ wstxLogger.arjLoggerI18N.error("com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.prepare_1", new Object[] { _id });
+ }
+ throw new SystemCommunicationException(ex.toString());
+ } else {
throw new SystemException(ex.toString());
- }
+ }
+ }
}
- public void confirm () throws InvalidParticipantException,
+ /**
+ * attempt to commit the participant
+ *
+ * @message com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.confirm_1 [com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.confirm_1] comms timeout attempting to commit WS-AT participant {0}
+ */
+ public void confirm () throws InvalidParticipantException,
WrongStateException, HeuristicHazardException,
HeuristicMixedException, HeuristicCancelException, SystemException
{
@@ -144,6 +166,10 @@
catch (com.arjuna.wst.SystemException ex)
{
if(ex instanceof com.arjuna.wst.stub.SystemCommunicationException) {
+ // log an error here -- we will end up writing a heuristic transaction record too
+ if (wstxLogger.arjLoggerI18N.isErrorEnabled()) {
+ wstxLogger.arjLoggerI18N.error("com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.confirm_1", new Object[] { _id });
+ }
throw new SystemCommunicationException(ex.toString());
} else {
throw new SystemException(ex.toString());
@@ -154,6 +180,11 @@
throw new InvalidParticipantException();
}
+ /**
+ * attempt to cancel the participant
+ *
+ * @message com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.cancel_1 [com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.cancel_1] comms timeout attempting to cancel WS-AT participant {0}
+ */
public void cancel () throws InvalidParticipantException,
WrongStateException, HeuristicHazardException,
HeuristicMixedException, HeuristicConfirmException, SystemException
@@ -181,7 +212,15 @@
// catch (com.arjuna.mw.wst.exceptions.SystemException ex)
catch (com.arjuna.wst.SystemException ex)
{
- throw new SystemException(ex.toString());
+ if(ex instanceof com.arjuna.wst.stub.SystemCommunicationException) {
+ // log an error here -- if the participant is dead it will retry anyway
+ if (wstxLogger.arjLoggerI18N.isErrorEnabled()) {
+ wstxLogger.arjLoggerI18N.error("com.arjuna.mwlabs.wst.at.participants.DurableTwoPhaseCommitParticipant.cancel_1", new Object[] { _id });
+ }
+ throw new SystemCommunicationException(ex.toString());
+ } else {
+ throw new SystemException(ex.toString());
+ }
}
}
else
@@ -190,7 +229,7 @@
// TODO mark ParticipantCancelledException explicitly?
- public void confirmOnePhase () throws InvalidParticipantException,
+ public void confirmOnePhase () throws InvalidParticipantException,
WrongStateException, HeuristicHazardException,
HeuristicMixedException, HeuristicCancelException, SystemException
{
@@ -202,9 +241,12 @@
{
v = prepare();
}
- catch (Exception ex)
+ catch (Exception ex)
{
- ex.printStackTrace();
+ // either the prepare timed out or the participant was invalid or in an
+ // invalid state
+
+ ex.printStackTrace();
v = new VoteCancel();
}
@@ -217,11 +259,15 @@
{
_rolledback = false;
- // TODO only do this if we didn't return VoteCancel
+ // TODO only do this if we didn't return VoteCancel
- cancel();
-
- throw new ParticipantCancelledException();
+ try {
+ cancel();
+ } catch (SystemCommunicationException sce) {
+ // if the rollback times out as well as the prepare we
+ // return an exception which indicates a failed transaction
+ }
+ throw new ParticipantCancelledException();
}
else
{
More information about the jboss-svn-commits
mailing list