This is an automated email from the ASF dual-hosted git repository.

apolovtsev pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new a30f9d68c52 IGNITE-28187 Non-transactional replica requests should be 
retried in the same manner as transactional (#7749)
a30f9d68c52 is described below

commit a30f9d68c5212cd404ebf4cc8691bac81e1eb07b
Author: Denis Chudov <[email protected]>
AuthorDate: Wed Mar 11 14:12:55 2026 +0200

    IGNITE-28187 Non-transactional replica requests should be retried in the 
same manner as transactional (#7749)
---
 .../apache/ignite/tx/RetriableReplicaRequestException.java} | 13 +++++++++----
 .../ignite/internal/lang/ComponentStoppingException.java    |  4 +++-
 .../apache/ignite/internal/lang/NodeStoppingException.java  |  4 +++-
 .../apache/ignite/internal/util/TrackerClosedException.java |  4 +++-
 .../internal/network/UnresolvableConsistentIdException.java |  4 +++-
 .../placementdriver/PrimaryReplicaAwaitException.java       |  4 +++-
 .../PrimaryReplicaAwaitTimeoutException.java                |  4 +++-
 .../replicator/exception/PrimaryReplicaMissException.java   |  3 ++-
 .../internal/replicator/exception/ReplicationException.java |  4 +++-
 .../table/distributed/storage/InternalTableImpl.java        | 13 +++----------
 .../internal/tx/impl/PrimaryReplicaExpiredException.java    |  4 +++-
 11 files changed, 38 insertions(+), 23 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
 
b/modules/api/src/main/java/org/apache/ignite/tx/RetriableReplicaRequestException.java
similarity index 68%
copy from 
modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
copy to 
modules/api/src/main/java/org/apache/ignite/tx/RetriableReplicaRequestException.java
index 2ab0b0e2d09..d41ff4084ff 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
+++ 
b/modules/api/src/main/java/org/apache/ignite/tx/RetriableReplicaRequestException.java
@@ -15,11 +15,16 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.util;
+package org.apache.ignite.tx;
 
 /**
- * Exception that will be thrown when the {@link 
PendingComparableValuesTracker} is closed.
+ * This is the marker interface for exceptions that may be thrown during 
replica requests and may be retried, such as:
+ * <ul>
+ *     <li>primary replica miss and primary replica expired exception;</li>
+ *     <li>replication problems;</li>
+ *     <li>replica unavailability;</li>
+ * </ul>
+ * etc.
  */
-public class TrackerClosedException extends RuntimeException {
-    private static final long serialVersionUID = -3685913884384983930L;
+public interface RetriableReplicaRequestException {
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
index 06354bfe440..710bcef5e51 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/lang/ComponentStoppingException.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.lang;
 import static org.apache.ignite.lang.ErrorGroups.Common.INTERNAL_ERR;
 
 import java.util.UUID;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 import org.jetbrains.annotations.Nullable;
 
@@ -28,7 +29,8 @@ import org.jetbrains.annotations.Nullable;
  * This is different from {@link NodeStoppingException} as {@link 
ComponentStoppingException} might mean that just the component is stopped,
  * not the whole node.
  */
-public class ComponentStoppingException extends IgniteInternalCheckedException 
implements RetriableTransactionException {
+public class ComponentStoppingException extends IgniteInternalCheckedException 
implements RetriableTransactionException,
+        RetriableReplicaRequestException {
     /** Serial version UID. */
     private static final long serialVersionUID = 0L;
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
index 35fd72fc99f..55a5ac34edd 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/lang/NodeStoppingException.java
@@ -20,13 +20,15 @@ package org.apache.ignite.internal.lang;
 import static org.apache.ignite.lang.ErrorGroups.Common.NODE_STOPPING_ERR;
 
 import java.util.UUID;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 import org.jetbrains.annotations.Nullable;
 
 /**
  * This exception is used to indicate that Ignite node is stopping (already 
stopped) for some reason.
  */
-public class NodeStoppingException extends IgniteInternalCheckedException 
implements RetriableTransactionException {
+public class NodeStoppingException extends IgniteInternalCheckedException 
implements RetriableTransactionException,
+        RetriableReplicaRequestException {
     /** Serial version UID. */
     private static final long serialVersionUID = 0L;
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
index 2ab0b0e2d09..92a3e693874 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/util/TrackerClosedException.java
@@ -17,9 +17,11 @@
 
 package org.apache.ignite.internal.util;
 
+import org.apache.ignite.tx.RetriableReplicaRequestException;
+
 /**
  * Exception that will be thrown when the {@link 
PendingComparableValuesTracker} is closed.
  */
-public class TrackerClosedException extends RuntimeException {
+public class TrackerClosedException extends RuntimeException implements 
RetriableReplicaRequestException {
     private static final long serialVersionUID = -3685913884384983930L;
 }
diff --git 
a/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
 
b/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
index fd53468f9bb..216466c66ba 100644
--- 
a/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
+++ 
b/modules/network-api/src/main/java/org/apache/ignite/internal/network/UnresolvableConsistentIdException.java
@@ -19,13 +19,15 @@ package org.apache.ignite.internal.network;
 
 import org.apache.ignite.lang.ErrorGroups.Network;
 import org.apache.ignite.lang.IgniteException;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 
 /**
  * Thrown when consistent ID cannot be resolved to a {@link 
InternalClusterNode} instance (i.e. when
  * there is no node with such consistent ID in the physical topology).
  */
-public class UnresolvableConsistentIdException extends IgniteException 
implements RetriableTransactionException {
+public class UnresolvableConsistentIdException extends IgniteException 
implements RetriableTransactionException,
+        RetriableReplicaRequestException {
     public UnresolvableConsistentIdException(String msg) {
         super(Network.UNRESOLVABLE_CONSISTENT_ID_ERR, msg);
     }
diff --git 
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
 
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
index 39ae5402dda..74d2a78b67d 100644
--- 
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
+++ 
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitException.java
@@ -22,13 +22,15 @@ import static 
org.apache.ignite.lang.ErrorGroups.PlacementDriver.PRIMARY_REPLICA
 import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 
 /**
  * The exception is thrown when a primary replica await process has failed. 
Please pay attention that there is a specific
  * {@link PrimaryReplicaAwaitTimeoutException} for the primary replica await 
timeout.
  */
-public class PrimaryReplicaAwaitException extends IgniteInternalException 
implements RetriableTransactionException {
+public class PrimaryReplicaAwaitException extends IgniteInternalException 
implements RetriableTransactionException,
+        RetriableReplicaRequestException {
     private static final long serialVersionUID = 1029917546884926160L;
 
     /**
diff --git 
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
 
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
index 633a2d93cdc..e584057528e 100644
--- 
a/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
+++ 
b/modules/placement-driver-api/src/main/java/org/apache/ignite/internal/placementdriver/PrimaryReplicaAwaitTimeoutException.java
@@ -22,13 +22,15 @@ import static 
org.apache.ignite.lang.ErrorGroups.PlacementDriver.PRIMARY_REPLICA
 import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 import org.jetbrains.annotations.Nullable;
 
 /**
  * The exception is thrown when a primary replica await process has times out.
  */
-public class PrimaryReplicaAwaitTimeoutException extends 
IgniteInternalException implements RetriableTransactionException {
+public class PrimaryReplicaAwaitTimeoutException extends 
IgniteInternalException implements RetriableTransactionException,
+        RetriableReplicaRequestException {
     private static final long serialVersionUID = -1450288033816499192L;
 
     /**
diff --git 
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
 
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
index 809eb26f9c5..184003b3511 100644
--- 
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
+++ 
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/PrimaryReplicaMissException.java
@@ -23,6 +23,7 @@ import static 
org.apache.ignite.lang.ErrorGroups.Replicator.REPLICA_MISS_ERR;
 import java.util.UUID;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 import org.jetbrains.annotations.Nullable;
 
@@ -30,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
  * Unchecked exception that is thrown when a replica is not the current 
primary replica.
  */
 public class PrimaryReplicaMissException extends IgniteInternalException 
implements ExpectedReplicationException,
-        RetriableTransactionException {
+        RetriableTransactionException, RetriableReplicaRequestException {
     private static final long serialVersionUID = 8755220779942651494L;
 
     /**
diff --git 
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
 
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
index 57a18d868d3..ea8360231dc 100644
--- 
a/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
+++ 
b/modules/replicator/src/main/java/org/apache/ignite/internal/replicator/exception/ReplicationException.java
@@ -22,12 +22,14 @@ import static 
org.apache.ignite.lang.ErrorGroups.Replicator.REPLICA_COMMON_ERR;
 import java.util.UUID;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.replicator.ReplicationGroupId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 
 /**
  * The exception is thrown when some issue happened during a replication.
  */
-public class ReplicationException extends IgniteInternalException implements 
RetriableTransactionException {
+public class ReplicationException extends IgniteInternalException implements 
RetriableTransactionException,
+        RetriableReplicaRequestException {
     /**
      * Constructor.
      *
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
index 662ce943e43..42ffcaec2cc 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/storage/InternalTableImpl.java
@@ -91,7 +91,6 @@ import org.apache.ignite.internal.hlc.HybridTimestampTracker;
 import org.apache.ignite.internal.lang.IgniteTriFunction;
 import org.apache.ignite.internal.network.ClusterNodeResolver;
 import org.apache.ignite.internal.network.InternalClusterNode;
-import org.apache.ignite.internal.network.UnresolvableConsistentIdException;
 import 
org.apache.ignite.internal.partition.replicator.network.PartitionReplicationMessagesFactory;
 import 
org.apache.ignite.internal.partition.replicator.network.replication.BinaryTupleMessage;
 import 
org.apache.ignite.internal.partition.replicator.network.replication.ReadOnlyMultiRowPkReplicaRequest;
@@ -106,9 +105,7 @@ import 
org.apache.ignite.internal.placementdriver.PlacementDriver;
 import org.apache.ignite.internal.placementdriver.ReplicaMeta;
 import org.apache.ignite.internal.replicator.ReplicaService;
 import org.apache.ignite.internal.replicator.ZonePartitionId;
-import 
org.apache.ignite.internal.replicator.exception.PrimaryReplicaMissException;
 import org.apache.ignite.internal.replicator.exception.ReplicationException;
-import 
org.apache.ignite.internal.replicator.exception.ReplicationTimeoutException;
 import org.apache.ignite.internal.replicator.message.ReplicaMessagesFactory;
 import org.apache.ignite.internal.replicator.message.ReplicaRequest;
 import org.apache.ignite.internal.replicator.message.ReplicationGroupIdMessage;
@@ -137,6 +134,7 @@ import org.apache.ignite.internal.util.IgniteUtils;
 import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.table.QualifiedName;
 import org.apache.ignite.table.QualifiedNameHelper;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.TransactionException;
 import org.jetbrains.annotations.Nullable;
 
@@ -2263,13 +2261,8 @@ public class InternalTableImpl implements InternalTable {
                                     e = e.getCause();
                                 }
 
-                                // We do a retry for the following conditions:
-                                // 1. Primary Replica has changed between the 
"awaitPrimaryReplica" and "invoke" calls;
-                                // 2. Primary Replica has died and is no 
longer available.
-                                // In both cases, we need to wait for the 
lease to expire and to get a new Primary Replica.
-                                if (e instanceof PrimaryReplicaMissException
-                                        || e instanceof 
UnresolvableConsistentIdException
-                                        || e instanceof 
ReplicationTimeoutException) {
+                                // We can do a retry for the any condition 
listed in javadoc for RetriableReplicaRequestException.
+                                if (e instanceof 
RetriableReplicaRequestException) {
                                     if (numRetries == 0) {
                                         throw new 
IgniteException(REPLICA_MISS_ERR, e);
                                     }
diff --git 
a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
 
b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
index fc951e706ba..e5232d6a9b1 100644
--- 
a/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
+++ 
b/modules/transactions/src/main/java/org/apache/ignite/internal/tx/impl/PrimaryReplicaExpiredException.java
@@ -23,11 +23,13 @@ import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.placementdriver.ReplicaMeta;
 import org.apache.ignite.internal.replicator.ZonePartitionId;
+import org.apache.ignite.tx.RetriableReplicaRequestException;
 import org.apache.ignite.tx.RetriableTransactionException;
 import org.jetbrains.annotations.Nullable;
 
 /** Unchecked exception that is thrown when primary replica has expired. */
-public class PrimaryReplicaExpiredException extends IgniteInternalException 
implements RetriableTransactionException {
+public class PrimaryReplicaExpiredException extends IgniteInternalException 
implements RetriableTransactionException,
+        RetriableReplicaRequestException {
     /**
      * The constructor.
      *

Reply via email to