[jboss-svn-commits] JBL Code SVN: r35174 - in labs/jbosstm/trunk/XTS: WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at and 5 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Sep 17 04:11:55 EDT 2010
Author: adinn
Date: 2010-09-17 04:11:54 -0400 (Fri, 17 Sep 2010)
New Revision: 35174
Added:
labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/ConfirmCompletedParticipant.java
Modified:
labs/jbosstm/trunk/XTS/WS-T/build.xml
labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryModule.java
labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryModule.java
labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorCompletionParticipantEngine.java
labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/ParticipantCompletionParticipantEngine.java
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBASubordinateRecoveryModule.java
Log:
fixes for JBTM-786
Modified: labs/jbosstm/trunk/XTS/WS-T/build.xml
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/build.xml 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/WS-T/build.xml 2010-09-17 08:11:54 UTC (rev 35174)
@@ -86,7 +86,8 @@
org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryModule.class
org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManager.class"/>
<property name="ws-t10.api.classes" value="com/arjuna/wst/BAParticipantManager.class"/>
- <property name="ws-t11.api.classes" value="com/arjuna/wst11/BAParticipantManager.class"/>
+ <property name="ws-t11.api.classes" value="com/arjuna/wst11/BAParticipantManager.class
+ com/arjuna/wst11/ConfirmCompletedParticipant.class"/>
<!--sibling module directories and jars -->
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryModule.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryModule.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -36,4 +36,12 @@
* durable participant
*/
public Durable2PCParticipant recreate(String id, byte[] recoveryState) throws Exception;
+
+ /**
+ * participant recovery modules may need to perform special processing when the a recovery scan has
+ * completed. in particular it is only after the first recovery scan has completed they can identify
+ * whether locally prepared changes are accompanied by a recreated participant and roll back changes
+ * for those with no such participant.
+ */
+ public void endScan();
}
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryModule.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryModule.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -71,4 +71,12 @@
*/
public BusinessAgreementWithCoordinatorCompletionParticipant
recreateCoordinatorCompletionParticipant(String id, byte[] recoveryState) throws Exception;
+
+ /**
+ * participant recovery modules may need to perform special processing when the a recovery scan has
+ * completed. in particular it is only after the first recovery scan has completed they can identify
+ * whether locally prepared changes are accompanied by a recreated participant and roll back changes
+ * for those with no such participant.
+ */
+ public void endScan();
}
\ No newline at end of file
Added: labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/ConfirmCompletedParticipant.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/ConfirmCompletedParticipant.java (rev 0)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/ConfirmCompletedParticipant.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -0,0 +1,68 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a full listing
+ * of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ * You should have received a copy of the GNU Lesser General Public License,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+package com.arjuna.wst11;
+
+/**
+ * This interface can be implemented by a BA participant in order to allow it to perform
+ * its complete operation in two phases. This enables the participant to prepare
+ * changes to persistent state and then commit them i) after the participant recovery
+ * record has been written to disk but ii) before the coordinator is notified that the
+ * participant has completed.
+ *
+ * A participant completion participant is expected to prepare its changes before calling
+ * completed. The BA implementation will call confirmCompleted after writing a recovery
+ * record, ensuring compensation is possible before the changes are persisted. It will
+ * not notify the coordinator that the participant has completed until after the callback
+ * returns, ensuring that any notification received by the coordinator is valid.
+ *
+ * A coordinator completion participant is expected to prepare its changes when its
+ * completed method is called and then return. The BA implementation will call
+ * confirmCompleted after writing a recovery record, ensuring compensation is possible
+ * before the changes are persisted. It will not notify the coordinator that the
+ * participant has completed until after the callback returns, ensuring that any
+ * notification received by the coordinator is valid.
+ *
+ * The associated participant recovery module must be able to detect uncommitted changes.
+ * The logged recovery record should include some sort of identifier tying the changes to the
+ * participant. If the recovery module identifies uncommitted changes with no associated
+ * recovery record then a crash happened between prepare and completed and this means the
+ * changes should be rolled back (presumed abort). If the recovery module identifies
+ * uncommitted changes with an associated recovery record then a crash happened after completed
+ * but before the confirmCompleted callback. The changes can be rolled forward and the participant
+ * recreated. Alternatively, the changes can be rolled back and the participant record rejected.
+ * If a recovery record is found with no uncommitted changes then the participant can be safely
+ * recreated, allowing the recovery manager to resend a committed message.
+ *
+ * It is possible that a completion operation may be initiated and then be cancelled part way through,
+ * e.g. because a CANCEL message is received from the coordinator while writing the log record. in this
+ * case the client will need to roll back any uncommitted changes. A boolean flag argument to the
+ * confirmCompleted method is used to distinguish this case. If the flag is supplied as true then
+ * changes should be committed. If it is supplied as false then changes should be rolled back.
+ */
+
+public interface ConfirmCompletedParticipant
+{
+ /**
+ * a participant callback use to notify the participant either that a recovery record has been written to
+ * the log and hence that uncommitted changes should be committed or that completion was cancelled and
+ * hence that uncommitted changes should be rolled back.
+ * @param confirmed true if the log record has been written and changes should be rolled forward and false
+ * if it has not been written and changes should be rolled back
+ */
+ public void confirmCompleted(boolean confirmed);
+}
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorCompletionParticipantEngine.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorCompletionParticipantEngine.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/CoordinatorCompletionParticipantEngine.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -24,6 +24,7 @@
import com.arjuna.webservices.logging.WSTLogger;
import com.arjuna.webservices.util.TransportTimer;
import com.arjuna.webservices11.wsaddr.AddressingHelper;
+import com.arjuna.wst11.ConfirmCompletedParticipant;
import org.jboss.wsf.common.addressing.MAP;
import com.arjuna.webservices11.wsarj.ArjunaContext;
import com.arjuna.webservices11.wsarj.InstanceIdentifier;
@@ -608,6 +609,7 @@
State current ;
boolean failRequired = false;
boolean deleteRequired = false;
+ boolean confirm = (participant instanceof ConfirmCompletedParticipant);
synchronized(this)
{
current = state ;
@@ -636,6 +638,12 @@
// record the fact that we have persisted this object so later operations will delete
// the log record
persisted = true;
+ // if necessary notify the client now. n.b. this has to be done synchronized because
+ // if we release the lock then a resent COMPLETE may result in a COMPLETED being
+ // sent back and we cannot allow that until after the confirm
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(true);
+ }
} else {
// we must force a fail but we don't have a log record to delete
changeState(State.STATE_FAILING_COMPLETING);
@@ -651,11 +659,19 @@
if (failRequired) {
current = fail(BusinessActivityConstants.WSBA_ELEMENT_FAIL_QNAME);
+ // we can safely do this now
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(false);
+ }
} else if (deleteRequired) {
if (!XTSBARecoveryManager.getRecoveryManager().deleteParticipantRecoveryRecord(id)) {
// hmm, could not delete entry log warning
WSTLogger.i18NLogger.warn_wst11_messaging_engines_ParticipantCompletionParticipantEngine_completed_2(id);
}
+ // we can safely do this now
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(false);
+ }
} else if ((current == State.STATE_COMPLETING) || (current == State.STATE_COMPLETED)) {
sendCompleted() ;
}
@@ -1313,6 +1329,7 @@
State current ;
boolean failRequired = false;
boolean deleteRequired = false;
+ boolean confirm = (participant instanceof ConfirmCompletedParticipant);
synchronized (this)
{
current = state ;
@@ -1343,6 +1360,12 @@
// record the fact that we have persisted this object so later operations will delete
// the log record
persisted = true;
+ // if necessary notify the client now. n.b. this has to be done synchronized because
+ // if we release the lock then a resent COMPLETE may result in a COMPLETED being
+ // sent back and we cannot allow that until after the confirm
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(true);
+ }
} else {
// we must force a fail but we don't have a log record to delete
changeState(State.STATE_FAILING_COMPLETING);
@@ -1359,11 +1382,18 @@
if (failRequired) {
current = fail(BusinessActivityConstants.WSBA_ELEMENT_FAIL_QNAME);
+ // we can safely do this now
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(false);
+ }
} else if (deleteRequired) {
if (!XTSBARecoveryManager.getRecoveryManager().deleteParticipantRecoveryRecord(id)) {
// hmm, could not delete entry log warning
WSTLogger.i18NLogger.warn_wst11_messaging_engines_ParticipantCompletionParticipantEngine_completed_2(id);
}
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(false);
+ }
} else if (current == State.STATE_COMPLETING) {
sendCompleted() ;
}
Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/ParticipantCompletionParticipantEngine.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/ParticipantCompletionParticipantEngine.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/messaging/engines/ParticipantCompletionParticipantEngine.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -24,6 +24,7 @@
import com.arjuna.webservices.logging.WSTLogger;
import com.arjuna.webservices.util.TransportTimer;
import com.arjuna.webservices11.wsaddr.AddressingHelper;
+import com.arjuna.wst11.ConfirmCompletedParticipant;
import org.jboss.wsf.common.addressing.MAP;
import com.arjuna.webservices11.wsarj.ArjunaContext;
import com.arjuna.webservices11.wsarj.InstanceIdentifier;
@@ -533,6 +534,7 @@
State current ;
boolean failRequired = false;
boolean deleteRequired = false;
+ boolean confirm = (participant instanceof ConfirmCompletedParticipant);
synchronized(this)
{
current = state ;
@@ -546,6 +548,12 @@
if (XTSBARecoveryManager.getRecoveryManager().writeParticipantRecoveryRecord(recoveryRecord)) {
changeState(State.STATE_COMPLETED);
persisted = true;
+ // if necessary notify the client now. n.b. this has to be done synchronized because
+ // if we release the lock then a resent COMPLETE may result in a COMPLETED being
+ // sent back and we cannot allow that until after the confirm
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(true);
+ }
} else {
// hmm, could not write entry log warning
WSTLogger.i18NLogger.warn_wst11_messaging_engines_ParticipantCompletionParticipantEngine_completed_1(id);
@@ -559,6 +567,10 @@
if (failRequired) {
current = fail(BusinessActivityConstants.WSBA_ELEMENT_FAIL_QNAME);
+ // we can safely do this now
+ if (confirm) {
+ ((ConfirmCompletedParticipant) participant).confirmCompleted(false);
+ }
} else if ((current == State.STATE_ACTIVE) || (current == State.STATE_COMPLETED)) {
sendCompleted() ;
}
Modified: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -232,6 +232,15 @@
}
}
+ // now let all the recovery modules know that we have completed a scan
+
+ Iterator<XTSATRecoveryModule> moduleIterator = recoveryModulesCopy.iterator();
+
+ while (moduleIterator.hasNext()) {
+ XTSATRecoveryModule recoveryModule = moduleIterator.next();
+ recoveryModule.endScan();
+ }
+
// ok, see if we are now in a position to cull any prepared subordinate transactions
cullOrphanedSubordinates();
Modified: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -33,4 +33,12 @@
}
return null;
}
+
+ /**
+ * we don't need to use this because the AT recovery manager tracks whether a subordinate AT scan has happened
+ */
+ public void endScan()
+ {
+ // do nothing
+ }
}
Modified: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -228,6 +228,15 @@
}
}
+ // now let all the recovery modules know that we have completed a scan
+
+ Iterator<XTSBARecoveryModule> moduleIterator = recoveryModulesCopy.iterator();
+
+ while (moduleIterator.hasNext()) {
+ XTSBARecoveryModule recoveryModule = moduleIterator.next();
+ recoveryModule.endScan();
+ }
+
// ok, see if we are now in a position to cull any prepared subordinate transactions
cullOrphanedSubordinates();
Modified: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBASubordinateRecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBASubordinateRecoveryModule.java 2010-09-17 05:58:57 UTC (rev 35173)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBASubordinateRecoveryModule.java 2010-09-17 08:11:54 UTC (rev 35174)
@@ -55,4 +55,12 @@
}
return null;
}
+
+ /**
+ * we don't need to use this because the BA recovery manager tracks whether a recovery scan has happened
+ */
+ public void endScan()
+ {
+ // do nothing
+ }
}
\ No newline at end of file
More information about the jboss-svn-commits
mailing list