From 5bf287bc9f92c5b0893e1dade87453be153d07c1 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 17 Dec 2013 16:30:13 +0000
Subject: [PATCH] OPENDJ-1172 Deadlock between replication threads during shutdown

---
 opends/src/server/org/opends/server/replication/server/changelog/je/ReplicationDB.java |   73 +++++++++++++-----------------------
 1 files changed, 27 insertions(+), 46 deletions(-)

diff --git a/opends/src/server/org/opends/server/replication/server/changelog/je/ReplicationDB.java b/opends/src/server/org/opends/server/replication/server/changelog/je/ReplicationDB.java
index 0fcb368..afe3adc 100644
--- a/opends/src/server/org/opends/server/replication/server/changelog/je/ReplicationDB.java
+++ b/opends/src/server/org/opends/server/replication/server/changelog/je/ReplicationDB.java
@@ -119,7 +119,7 @@
    * @param baseDN The baseDN of the replication domain.
    * @param replicationServer The ReplicationServer that needs to be shutdown.
    * @param dbenv The Db environment to use to create the db.
-   * @throws ChangelogException If a database problem happened.
+   * @throws ChangelogException If a database problem happened
    */
   public ReplicationDB(int serverId, DN baseDN,
       ReplicationServer replicationServer, ReplicationDbEnv dbenv)
@@ -184,9 +184,12 @@
   /**
    * add a list of changes to the underlying db.
    *
-   * @param changes The list of changes to add to the underlying db.
+   * @param changes
+   *          The list of changes to add to the underlying db.
+   * @throws ChangelogException
+   *           If a database problem happened
    */
-  public void addEntries(List<UpdateMsg> changes)
+  public void addEntries(List<UpdateMsg> changes) throws ChangelogException
   {
     dbCloseLock.readLock().lock();
     try
@@ -209,7 +212,7 @@
     }
     catch (DatabaseException e)
     {
-      dbenv.shutdownOnException(e);
+      throw new ChangelogException(e);
     }
     finally
     {
@@ -280,9 +283,9 @@
    * @param startCSN
    *          The CSN from which the cursor must start.If null, start from the
    *          oldest CSN
-   * @throws ChangelogException
-   *           When a problem occurs or the startCSN does not exist.
    * @return The ReplServerDBCursor.
+   * @throws ChangelogException
+   *           If a database problem happened
    */
   public ReplServerDBCursor openReadCursor(CSN startCSN)
       throws ChangelogException
@@ -320,8 +323,10 @@
    * Read the oldest CSN present in the database.
    *
    * @return the oldest CSN in the DB, null if the DB is empty or closed
+   * @throws ChangelogException
+   *           If a database problem happened
    */
-  public CSN readOldestCSN()
+  public CSN readOldestCSN() throws ChangelogException
   {
     dbCloseLock.readLock().lock();
 
@@ -362,8 +367,7 @@
     }
     catch (DatabaseException e)
     {
-      dbenv.shutdownOnException(e);
-      return null;
+      throw new ChangelogException(e);
     }
     finally
     {
@@ -375,8 +379,10 @@
    * Read the newest CSN present in the database.
    *
    * @return the newest CSN in the DB, null if the DB is empty or closed
+   * @throws ChangelogException
+   *           If a database problem happened
    */
-  public CSN readNewestCSN()
+  public CSN readNewestCSN() throws ChangelogException
   {
     dbCloseLock.readLock().lock();
 
@@ -419,8 +425,7 @@
     }
     catch (DatabaseException e)
     {
-      dbenv.shutdownOnException(e);
-      return null;
+      throw new ChangelogException(e);
     }
     finally
     {
@@ -435,8 +440,10 @@
    *          The CSN from which we start searching.
    * @return the CSN right before the one passed as a parameter. Can return null
    *         if there is none.
+   * @throws ChangelogException
+   *           If a database problem happened
    */
-  public CSN getPreviousCSN(CSN csn)
+  public CSN getPreviousCSN(CSN csn) throws ChangelogException
   {
     if (csn == null)
     {
@@ -479,7 +486,7 @@
     }
     catch (DatabaseException e)
     {
-      dbenv.shutdownOnException(e);
+      throw new ChangelogException(e);
     }
     finally
     {
@@ -652,12 +659,12 @@
       }
       catch (ChangelogException e)
       {
-        abort(localTxn);
+        JEUtils.abort(localTxn);
         throw e;
       }
       catch (Exception e)
       {
-        abort(localTxn);
+        JEUtils.abort(localTxn);
         throw new ChangelogException(e);
       }
       finally
@@ -669,21 +676,6 @@
       }
     }
 
-    private void abort(Transaction localTxn)
-    {
-      if (localTxn != null)
-      {
-        try
-        {
-          localTxn.abort();
-        }
-        catch (DatabaseException ignore)
-        {
-          // Ignore.
-        }
-      }
-    }
-
     /**
      * Close the ReplicationServer Cursor.
      */
@@ -716,9 +708,9 @@
     }
 
     /**
-     * Abort the Cursor after a Deadlock Exception.
-     * This method catch and ignore the DeadlockException because
-     * this must be done when aborting a cursor after a DeadlockException
+     * Abort the cursor after an Exception.
+     * This method catch and ignore the DatabaseException because
+     * this must be done when aborting a cursor after a DatabaseException
      * (per the Cursor documentation).
      * This should not be used in any other case.
      */
@@ -734,18 +726,7 @@
       }
 
       closeAndReleaseReadLock(cursor);
-
-      if (txn != null)
-      {
-        try
-        {
-          txn.abort();
-        }
-        catch (DatabaseException e)
-        {
-          dbenv.shutdownOnException(e);
-        }
-      }
+      JEUtils.abort(txn);
     }
 
     /**

--
Gitblit v1.10.0