| | |
| | | import org.forgerock.i18n.slf4j.LocalizedLogger; |
| | | import org.forgerock.opendj.config.server.ConfigChangeResult; |
| | | import org.forgerock.opendj.config.server.ConfigException; |
| | | import org.forgerock.opendj.config.server.ConfigurationChangeListener; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.util.Reject; |
| | | import org.forgerock.opendj.config.server.ConfigurationChangeListener; |
| | | import org.forgerock.opendj.server.config.server.PDBBackendCfg; |
| | | import org.forgerock.util.Reject; |
| | | import org.opends.server.api.Backupable; |
| | | import org.opends.server.api.DiskSpaceMonitorHandler; |
| | | import org.opends.server.backends.pluggable.spi.AccessMode; |
| | |
| | | } |
| | | |
| | | private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); |
| | | private final ThreadLocal<Boolean> isInsideWriteTransaction = new ThreadLocal<Boolean>(); |
| | | |
| | | private final ServerContext serverContext; |
| | | private final File backendDirectory; |
| | |
| | | { |
| | | // 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. |
| | | throwIfNestedInWriteTransaction(); |
| | | |
| | | final Transaction txn = db.getTransaction(); |
| | | for (;;) |
| | | { |
| | |
| | | @Override |
| | | public void write(final WriteOperation operation) throws Exception |
| | | { |
| | | throwIfNestedInWriteTransaction(); |
| | | |
| | | final Transaction txn = db.getTransaction(); |
| | | for (;;) |
| | | { |
| | | txn.begin(); |
| | | isInsideWriteTransaction.set(Boolean.TRUE); |
| | | try |
| | | { |
| | | try (final StorageImpl storageImpl = newStorageImpl()) |
| | |
| | | finally |
| | | { |
| | | txn.end(); |
| | | isInsideWriteTransaction.set(Boolean.FALSE); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 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() |
| | | { |
| | | if (Boolean.TRUE.equals(isInsideWriteTransaction.get())) |
| | | { |
| | | throw new IllegalStateException("OpenDJ does not support transactions nested in a write transaction. " |
| | | + "Code is forbidden from opening one."); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public boolean supportsBackupAndRestore() |
| | | { |