You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by es...@apache.org on 2018/01/22 21:17:42 UTC
[geode] 02/02: fix a race: FindRemoteTXMessageReply should not
modify tx commit message state as it does not hold the tx lock;
instead, clinet version is modified in TXRemoteCommitMessage when the tx
lock is held.
This is an automated email from the ASF dual-hosted git repository.
eshu11 pushed a commit to branch feature/GEODE-4142
in repository https://gitbox.apache.org/repos/asf/geode.git
commit 5828c00f6d67066882a5edd913735eaa42203936
Author: eshu <es...@pivotal.io>
AuthorDate: Mon Jan 22 13:10:03 2018 -0800
fix a race: FindRemoteTXMessageReply should not modify tx commit message state as it does not hold the tx lock;
instead, clinet version is modified in TXRemoteCommitMessage when the tx lock is held.
---
.../geode/internal/cache/FindRemoteTXMessage.java | 12 ++---
.../internal/cache/JtaAfterCompletionMessage.java | 5 +-
.../internal/cache/TXRemoteCommitMessage.java | 3 ++
.../sockets/command/TXSynchronizationCommand.java | 2 +-
.../internal/cache/TXRemoteCommitMessageTest.java | 54 ++++++++++++++++++++++
.../codeAnalysis/sanctionedDataSerializables.txt | 4 +-
6 files changed, 68 insertions(+), 12 deletions(-)
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/FindRemoteTXMessage.java b/geode-core/src/main/java/org/apache/geode/internal/cache/FindRemoteTXMessage.java
index bedd04d..7afb9db 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/FindRemoteTXMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/FindRemoteTXMessage.java
@@ -255,14 +255,12 @@ public class FindRemoteTXMessage extends HighPriorityDistributionMessage
public void toData(DataOutput out) throws IOException {
super.toData(out);
out.writeBoolean(this.isHostingTx);
- boolean sendTXCommitMessage = this.txCommitMessage != null;
+ // Do not send TxCommitMessage for TXFailover.
+ // FindRemoteTXMessage does not hold the tx lock and should not
+ // modify TXCommitMessage state to cause race condition.
+ // This will force a retry and use the TXRemoteCommitMessage to get the commit message.
+ boolean sendTXCommitMessage = false;
out.writeBoolean(sendTXCommitMessage);
- if (sendTXCommitMessage) {
- out.writeBoolean(this.isPartialCommitMessage);
- // since this message is going to a peer, reset client version
- txCommitMessage.setClientVersion(null); // fixes bug 46529
- InternalDataSerializer.writeDSFID(txCommitMessage, out);
- }
}
@Override
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/JtaAfterCompletionMessage.java b/geode-core/src/main/java/org/apache/geode/internal/cache/JtaAfterCompletionMessage.java
index d843ba8..96b8d33 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/JtaAfterCompletionMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/JtaAfterCompletionMessage.java
@@ -80,8 +80,9 @@ public class JtaAfterCompletionMessage extends TXMessage {
}
TXCommitMessage commitMessage = txMgr.getRecentlyCompletedMessage(txId);
if (commitMessage != null) {
- TXRemoteCommitReplyMessage.send(getSender(), getProcessorId(), commitMessage,
- getReplySender(dm));
+ TXCommitMessage message =
+ commitMessage == TXCommitMessage.ROLLBACK_MSG ? null : commitMessage;
+ TXRemoteCommitReplyMessage.send(getSender(), getProcessorId(), message, getReplySender(dm));
return false;
}
TXStateProxy txState = txMgr.getTXState();
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/TXRemoteCommitMessage.java b/geode-core/src/main/java/org/apache/geode/internal/cache/TXRemoteCommitMessage.java
index d9d5cb8..7960fb2 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/TXRemoteCommitMessage.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/TXRemoteCommitMessage.java
@@ -171,6 +171,9 @@ public class TXRemoteCommitMessage extends TXMessage {
public static void send(InternalDistributedMember recipient, int processorId,
TXCommitMessage val, ReplySender replySender) throws RemoteOperationException {
Assert.assertTrue(recipient != null, "TXRemoteCommitReply NULL reply message");
+ if (val != null) {
+ val.setClientVersion(null);
+ }
TXRemoteCommitReplyMessage m = new TXRemoteCommitReplyMessage(processorId, val);
m.setRecipient(recipient);
replySender.putOutgoing(m);
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/TXSynchronizationCommand.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
index c1fb616..2671e4e 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/command/TXSynchronizationCommand.java
@@ -96,7 +96,7 @@ public class TXSynchronizationCommand extends BaseCommand {
final TXId txId = txProxy.getTxId();
TXCommitMessage commitMessage = txMgr.getRecentlyCompletedMessage(txId);
- if (commitMessage != null) {
+ if (commitMessage != null && commitMessage != TXCommitMessage.ROLLBACK_MSG) {
assert type == CompletionType.AFTER_COMPLETION;
try {
CommitCommand.writeCommitResponse(commitMessage, clientMessage, serverConnection);
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/TXRemoteCommitMessageTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/TXRemoteCommitMessageTest.java
new file mode 100644
index 0000000..2724499
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/TXRemoteCommitMessageTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.internal.cache;
+
+import static org.junit.Assert.*;
+
+import java.io.DataInput;
+import java.io.DataOutputStream;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.internal.ByteArrayData;
+import org.apache.geode.test.junit.categories.UnitTest;
+
+@Category(UnitTest.class)
+public class TXRemoteCommitMessageTest {
+
+ @Test
+ public void testFindRemoteTXMessageReplyDoesNotSendCommitMessage() throws Exception {
+ FindRemoteTXMessage.FindRemoteTXMessageReply findRemoteTXMessageReply =
+ new FindRemoteTXMessage.FindRemoteTXMessageReply();
+ findRemoteTXMessageReply.isHostingTx = true;
+ findRemoteTXMessageReply.txCommitMessage = new TXCommitMessage();
+
+ ByteArrayData testStream = new ByteArrayData();
+ assertTrue(testStream.isEmpty());
+
+ DataOutputStream out = testStream.getDataOutput();
+ findRemoteTXMessageReply.toData(out);
+ assertTrue(testStream.size() > 0);
+
+ DataInput in = testStream.getDataInput();
+ FindRemoteTXMessage.FindRemoteTXMessageReply findRemoteTXMessageReplyFromData =
+ new FindRemoteTXMessage.FindRemoteTXMessageReply();
+ findRemoteTXMessageReplyFromData.fromData(in);
+
+ assertEquals(true, findRemoteTXMessageReplyFromData.isHostingTx);
+ assertNull(findRemoteTXMessageReplyFromData.txCommitMessage);
+ }
+}
diff --git a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
index e9a08a5..cf2c87a 100644
--- a/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
+++ b/geode-core/src/test/resources/org/apache/geode/codeAnalysis/sanctionedDataSerializables.txt
@@ -1031,8 +1031,8 @@ fromData,27,2a2bb700452a2bb80046c00047b500032a2bb900480100b50004b1
toData,24,2a2bb700422ab400032bb800432b2ab40004b900440200b1
org/apache/geode/internal/cache/FindRemoteTXMessage$FindRemoteTXMessageReply,2
-fromData,46,2a2bb7000a2a2bb9000b0100b500042bb9000b01009900182a2bb9000b0100b500072a2bb8000cc0000db50006b1
-toData,66,2a2bb700032b2ab40004b9000502002ab40006c6000704a70004033d2b1cb9000502001c99001d2b2ab40007b9000502002ab4000601b600082ab400062bb80009b1
+fromData,46,2a2bb700062a2bb900070100b500042bb9000701009900182a2bb900070100b500082a2bb80009c0000ab5000bb1
+toData,25,2a2bb700032b2ab40004b900050200033d2b1cb900050200b1
org/apache/geode/internal/cache/FindVersionTagOperation$FindVersionTagMessage,2
fromData,55,2a2bb700232a2bb900240100b500032a2bb900250100b500042abb002659b70027b500052ab400052bb800282a2bb900290100b50006b1
--
To stop receiving notification emails like this one, please contact
eshu11@apache.org.