From d6a5316c7055055f2da0310748dc5a46dc777144 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 19 Aug 2026 08:37:49 +0000
Subject: [PATCH] [#870] Stop replaying a rolled back read in the PersistIt backend (#871)

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java |   43 ++++++++++++++++++++++---------------------
 1 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java
index a4e6f97..ea23395 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java
@@ -598,29 +598,30 @@
     @Override
     public <T> T read(ReadOperation<T> operation) throws Exception
     {
+      /*
+       * A rolled back read is not replayed. Unlike WriteOperation, a ReadOperation is not required to be
+       * idempotent, and four of them are not: ExportJob has written entries to its LDIF stream, whose writer is
+       * opened once so that a replay appends rather than truncates; VerifyJob has accumulated its counters in
+       * instance fields that no attempt resets; and the two reads of BackendStat have printed records and
+       * appended to a map owned by their caller. Replaying corrupts their result rather than repairing it, so
+       * the failure goes to the caller, as it does in the JE, Cassandra and JDBC backends.
+       */
       final Transaction txn = db.getTransaction();
-      for (;;)
+      txn.begin();
+      try
       {
-        txn.begin();
-        try
-        {
-          final T result = operation.run(this);
-          txn.commit(commitPolicy);
-          return result;
-        }
-        catch (final RollbackException e)
-        {
-          // retry
-        }
-        catch (final Exception e)
-        {
-          txn.rollback();
-          throw e;
-        }
-        finally
-        {
-          txn.end();
-        }
+        final T result = operation.run(this);
+        txn.commit(commitPolicy);
+        return result;
+      }
+      catch (final Exception e)
+      {
+        txn.rollback();
+        throw e;
+      }
+      finally
+      {
+        txn.end();
       }
     }
 

--
Gitblit v1.10.0