From 733732be7ba61275e3855d316654970360b525f3 Mon Sep 17 00:00:00 2001 From: Manoj Govindassamy Date: Sat, 18 Dec 2021 08:43:10 -0800 Subject: [PATCH] [HUDI-3029] Transaction manager: avoid deadlock when doing begin and end transactions (#4373) --- .../client/transaction/TransactionManager.java | 2 +- .../transaction/TestTransactionManager.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/client/transaction/TransactionManager.java b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/client/transaction/TransactionManager.java index 3a3552e74..d9b9d3d26 100644 --- a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/client/transaction/TransactionManager.java +++ b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/client/transaction/TransactionManager.java @@ -85,7 +85,7 @@ public class TransactionManager implements Serializable { private synchronized void reset(Option callerInstant, Option newTxnOwnerInstant, Option lastCompletedTxnOwnerInstant) { - if (!this.currentTxnOwnerInstant.isPresent() || this.currentTxnOwnerInstant == callerInstant) { + if (!this.currentTxnOwnerInstant.isPresent() || this.currentTxnOwnerInstant.get().equals(callerInstant.get())) { this.currentTxnOwnerInstant = newTxnOwnerInstant; this.lastCompletedTxnOwnerInstant = lastCompletedTxnOwnerInstant; } diff --git a/hudi-client/hudi-client-common/src/test/java/org/apache/hudi/client/transaction/TestTransactionManager.java b/hudi-client/hudi-client-common/src/test/java/org/apache/hudi/client/transaction/TestTransactionManager.java index 5589dff2c..a1a7f6a31 100644 --- a/hudi-client/hudi-client-common/src/test/java/org/apache/hudi/client/transaction/TestTransactionManager.java +++ b/hudi-client/hudi-client-common/src/test/java/org/apache/hudi/client/transaction/TestTransactionManager.java @@ -190,6 +190,22 @@ public class TestTransactionManager extends HoodieCommonTestHarness { transactionManager.endTransaction(); Assertions.assertFalse(transactionManager.getCurrentTransactionOwner().isPresent()); Assertions.assertFalse(transactionManager.getLastCompletedTransactionOwner().isPresent()); + + // 5. Transactions with new instants but with same timestamps should properly reset owners + transactionManager.beginTransaction(getInstant("0000005"), Option.empty()); + Assertions.assertTrue(transactionManager.getCurrentTransactionOwner().isPresent()); + Assertions.assertFalse(transactionManager.getLastCompletedTransactionOwner().isPresent()); + transactionManager.endTransaction(getInstant("0000005")); + Assertions.assertFalse(transactionManager.getCurrentTransactionOwner().isPresent()); + Assertions.assertFalse(transactionManager.getLastCompletedTransactionOwner().isPresent()); + + // 6. Transactions with no owners should also go through + transactionManager.beginTransaction(Option.empty(), Option.empty()); + Assertions.assertFalse(transactionManager.getCurrentTransactionOwner().isPresent()); + Assertions.assertFalse(transactionManager.getLastCompletedTransactionOwner().isPresent()); + transactionManager.endTransaction(Option.empty()); + Assertions.assertFalse(transactionManager.getCurrentTransactionOwner().isPresent()); + Assertions.assertFalse(transactionManager.getLastCompletedTransactionOwner().isPresent()); } private Option getInstant(String timestamp) {