denis-chudov commented on code in PR #2757:
URL: https://github.com/apache/ignite-3/pull/2757#discussion_r1374212479


##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/ReadWriteTransactionImpl.java:
##########
@@ -56,6 +62,12 @@ public class ReadWriteTransactionImpl extends 
IgniteAbstractTransactionImpl {
     /** A partition which stores the transaction state. */
     private volatile TablePartitionId commitPart;
 
+    /** The lock protects the transaction topology from concurrent 
modification during finishing. */
+    private final ReentrantReadWriteLock enlistPartLock = new 
ReentrantReadWriteLock();

Review Comment:
   Lets choose human-understandable names :) What about "enlistPartitionLock"?



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/ReadWriteTransactionImpl.java:
##########
@@ -90,12 +102,57 @@ public IgniteBiTuple<ClusterNode, Long> 
enlistedNodeAndTerm(TablePartitionId par
     /** {@inheritDoc} */
     @Override
     public IgniteBiTuple<ClusterNode, Long> enlist(TablePartitionId 
tablePartitionId, IgniteBiTuple<ClusterNode, Long> nodeAndTerm) {
-        return enlisted.computeIfAbsent(tablePartitionId, k -> nodeAndTerm);
+        checkEnlistReady();
+
+        try {
+            enlistPartLock.readLock().lock();
+
+            checkEnlistReady();
+
+            return enlisted.computeIfAbsent(tablePartitionId, k -> 
nodeAndTerm);
+        } finally {
+            enlistPartLock.readLock().unlock();
+        }
+    }
+
+    /**
+     * Checks that this transaction was not finished and will be able to 
enlist another partition.
+     */
+    private void checkEnlistReady() {
+        if (isFinalState(state())) {
+            throw new TransactionException(
+                    TX_FAILED_READ_WRITE_OPERATION_ERR,
+                    format("Transaction is already finished [id={}, 
state={}].", id(), state()));
+        }
     }
 
     /** {@inheritDoc} */
     @Override
     protected CompletableFuture<Void> finish(boolean commit) {
+        if (isFinalState(state())) {
+            return finishFuture;
+        }
+
+        try {
+            enlistPartLock.writeLock().lock();
+
+            if (!isFinalState(state())) {
+                finishFuture =  finishInternal(commit);

Review Comment:
   2 spaces instead of one



##########
modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/ReadWriteTransactionImpl.java:
##########
@@ -90,12 +102,57 @@ public IgniteBiTuple<ClusterNode, Long> 
enlistedNodeAndTerm(TablePartitionId par
     /** {@inheritDoc} */
     @Override
     public IgniteBiTuple<ClusterNode, Long> enlist(TablePartitionId 
tablePartitionId, IgniteBiTuple<ClusterNode, Long> nodeAndTerm) {
-        return enlisted.computeIfAbsent(tablePartitionId, k -> nodeAndTerm);
+        checkEnlistReady();
+
+        try {
+            enlistPartLock.readLock().lock();
+
+            checkEnlistReady();
+
+            return enlisted.computeIfAbsent(tablePartitionId, k -> 
nodeAndTerm);
+        } finally {
+            enlistPartLock.readLock().unlock();
+        }
+    }
+
+    /**
+     * Checks that this transaction was not finished and will be able to 
enlist another partition.
+     */
+    private void checkEnlistReady() {
+        if (isFinalState(state())) {
+            throw new TransactionException(
+                    TX_FAILED_READ_WRITE_OPERATION_ERR,
+                    format("Transaction is already finished [id={}, 
state={}].", id(), state()));
+        }
     }
 
     /** {@inheritDoc} */
     @Override
     protected CompletableFuture<Void> finish(boolean commit) {
+        if (isFinalState(state())) {
+            return finishFuture;
+        }
+
+        try {
+            enlistPartLock.writeLock().lock();
+
+            if (!isFinalState(state())) {
+                finishFuture =  finishInternal(commit);
+            }
+
+            return finishFuture;
+        } finally {
+            enlistPartLock.writeLock().unlock();
+        }
+    }
+
+    /**
+     * Internal method to finishing this transaction.

Review Comment:
   ```suggestion
        * Internal method for finishing this transaction.
   ```



##########
modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/api/ItCommonApiTest.java:
##########
@@ -152,7 +152,6 @@ public void checkTimestampOperations() {
 
     /** Check transaction change status with erroneous statements. */
     @Test
-    // TODO should be removed after 
https://issues.apache.org/jira/browse/IGNITE-20534  is fixed.
     public void testTxStateChangedOnErroneousOp() {

Review Comment:
   seems there was an intention to remove the test after the fix (but I still 
cant get why), and you just removed todo - what is correct here?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscr...@ignite.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to