diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java index 3f0ba37..f43b65f 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureExecutor.java @@ -635,34 +635,23 @@ public class ProcedureExecutor { Preconditions.checkArgument(lastProcId.get() >= 0); Preconditions.checkArgument(!proc.hasParent()); - Long currentProcId; - - // The following part of the code has to be synchronized to prevent multiple request - // with the same nonce to execute at the same time. - synchronized (this) { - // Check whether the proc exists. If exist, just return the proc id. - // This is to prevent the same proc to submit multiple times (it could happen - // when client could not talk to server and resubmit the same request). - NonceKey noncekey = null; - if (nonce != HConstants.NO_NONCE) { - noncekey = new NonceKey(nonceGroup, nonce); - currentProcId = nonceKeysToProcIdsMap.get(noncekey); - if (currentProcId != null) { - // Found the proc - return currentProcId; - } + // Initialize the Procedure ID + long currentProcId = nextProcId(); + proc.setProcId(currentProcId); + + // Check whether the proc exists. If exist, just return the proc id. + // This is to prevent the same proc to submit multiple times (it could happen + // when client could not talk to server and resubmit the same request). + if (nonce != HConstants.NO_NONCE) { + NonceKey noncekey = new NonceKey(nonceGroup, nonce); + proc.setNonceKey(noncekey); + + Long oldProcId = nonceKeysToProcIdsMap.putIfAbsent(noncekey, currentProcId); + if (oldProcId != null) { + // Found the proc + return oldProcId.longValue(); } - - // Initialize the Procedure ID - currentProcId = nextProcId(); - proc.setProcId(currentProcId); - - // This is new procedure. Set the noncekey and insert into the map. - if (noncekey != null) { - proc.setNonceKey(noncekey); - nonceKeysToProcIdsMap.put(noncekey, currentProcId); - } - } // end of synchronized (this) + } // Commit the transaction store.insert(proc, null); diff --git a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java index 18df398..da60674 100644 --- a/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java +++ b/hbase-procedure/src/test/java/org/apache/hadoop/hbase/procedure2/TestProcedureRecovery.java @@ -303,7 +303,7 @@ public class TestProcedureRecovery { Procedure proc2 = new TestSingleStepProcedure(); // Submit a procedure with the same nonce and expect the same procedure would return. long procId2 = ProcedureTestingUtility.submitAndWait(procExecutor, proc2, nonceGroup, nonce); - assertTrue(procId == procId2); + assertEquals(procId, procId2); ProcedureInfo result = procExecutor.getResult(procId2); ProcedureTestingUtility.assertProcNotFailed(result); @@ -327,7 +327,7 @@ public class TestProcedureRecovery { procEnv.setWaitLatch(null); // The original proc is not completed and the new submission should have the same proc Id. - assertTrue(procId == procId2); + assertEquals(procId, procId2); }