From 546f13400a1ccf9305d2f71c546663256aa8890b Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 21 Dec 2015 09:19:15 +0000
Subject: [PATCH] OPENDJ-2554 Forbid nested transactions in PDB

---
 opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 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 8b90b1f..6b64ef3 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
@@ -863,6 +863,12 @@
   public <T> T read(final ReadOperation<T> operation) throws Exception
   {
     final Transaction txn = db.getTransaction();
+    // This check may be unnecessary for PDB, but it will help us detect bad business logic
+    // in the pluggable backend that would cause problems for JE.
+    // A nested read would be a serious problem for the JE storage
+    // as it could result in self-deadlock where an inner read attempts to read-lock a record
+    // that has been write-locked in an outer write.
+    throwIfTransactionIsNested(txn);
     for (;;)
     {
       txn.begin();
@@ -910,6 +916,7 @@
   public void write(final WriteOperation operation) throws Exception
   {
     final Transaction txn = db.getTransaction();
+    throwIfTransactionIsNested(txn);
     for (;;)
     {
       txn.begin();
@@ -947,6 +954,16 @@
     }
   }
 
+  private void throwIfTransactionIsNested(final Transaction txn)
+  {
+    final int txnDepth = txn.getNestedTransactionDepth();
+    if (txnDepth > 0)
+    {
+      throw new IllegalStateException("OpenDJ does not use nested transactions. "
+          + "Code is forbidden from opening one.");
+    }
+  }
+
   @Override
   public boolean supportsBackupAndRestore()
   {

--
Gitblit v1.10.0