From a9df049d29e7d36a75d941babd467b7b91acb09e Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Wed, 09 Mar 2016 09:30:32 +0000
Subject: [PATCH] OPENDJ-2645 numSubordinates attribute not returned when using PDB
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pdb/PDBStorage.java | 33 ++++++++++++++++++++++-----------
1 files changed, 22 insertions(+), 11 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 4b9d7cd..5d7637f 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
@@ -11,7 +11,7 @@
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions Copyright [year] [name of copyright owner]".
*
- * Copyright 2014-2015 ForgeRock AS.
+ * Copyright 2014-2016 ForgeRock AS.
*/
package org.opends.server.backends.pdb;
@@ -709,6 +709,8 @@
}
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+ private final ThreadLocal<Boolean> isInsideWriteTransaction = new ThreadLocal<Boolean>();
+
private final ServerContext serverContext;
private final File backendDirectory;
private AccessMode accessMode;
@@ -852,13 +854,11 @@
@Override
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);
+ throwIfNestedInWriteTransaction();
+
+ final Transaction txn = db.getTransaction();
for (;;)
{
txn.begin();
@@ -905,11 +905,13 @@
@Override
public void write(final WriteOperation operation) throws Exception
{
+ throwIfNestedInWriteTransaction();
+
final Transaction txn = db.getTransaction();
- throwIfTransactionIsNested(txn);
for (;;)
{
txn.begin();
+ isInsideWriteTransaction.set(Boolean.TRUE);
try
{
try (final StorageImpl storageImpl = newStorageImpl())
@@ -940,16 +942,25 @@
finally
{
txn.end();
+ isInsideWriteTransaction.set(Boolean.FALSE);
}
}
}
- private void throwIfTransactionIsNested(final Transaction txn)
+ /**
+ * A nested transaction within a write transaction may cause a self-deadlock where an inner read
+ * attempts to read-lock a record that has been write-locked in an outer write.
+ * <p>
+ * It would also be good to forbid any nested transactions, but it is impractical due to some
+ * transactions being deeply nested into the call hierarchy.
+ *
+ * @see <a href="https://bugster.forgerock.org/jira/browse/OPENDJ-2645">OPENDJ-2645</a>
+ */
+ private void throwIfNestedInWriteTransaction()
{
- final int txnDepth = txn.getNestedTransactionDepth();
- if (txnDepth > 0)
+ if (Boolean.TRUE.equals(isInsideWriteTransaction.get()))
{
- throw new IllegalStateException("OpenDJ does not use nested transactions. "
+ throw new IllegalStateException("OpenDJ does not support transactions nested in a write transaction. "
+ "Code is forbidden from opening one.");
}
}
--
Gitblit v1.10.0