From 2af7525dc754ba78d7dc21d059d7c0b30b97ece9 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 27 Oct 2015 11:12:28 +0000
Subject: [PATCH] OPENDJ-2335: prevent JE index corruption due to phantom reads
---
opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/JEStorage.java | 31 ++++++++++++++++++++-----------
1 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/JEStorage.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/JEStorage.java
index 2ad53f2..30e4cc7 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/JEStorage.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/jeb/JEStorage.java
@@ -464,24 +464,33 @@
{
try
{
- Database tree = getOrOpenTree(treeName);
- DatabaseEntry dbKey = db(key);
- DatabaseEntry dbValue = new DatabaseEntry();
-
- boolean isDefined = tree.get(txn, dbKey, dbValue, RMW) == SUCCESS;
- final ByteSequence oldValue = valueToBytes(dbValue, isDefined);
- final ByteSequence newValue = f.computeNewValue(oldValue);
- if (!Objects.equals(newValue, oldValue))
+ final Database tree = getOrOpenTree(treeName);
+ final DatabaseEntry dbKey = db(key);
+ final DatabaseEntry dbValue = new DatabaseEntry();
+ for (;;)
{
+ final boolean isDefined = tree.get(txn, dbKey, dbValue, RMW) == SUCCESS;
+ final ByteSequence oldValue = valueToBytes(dbValue, isDefined);
+ final ByteSequence newValue = f.computeNewValue(oldValue);
+ if (Objects.equals(newValue, oldValue))
+ {
+ return false;
+ }
if (newValue == null)
{
return tree.delete(txn, dbKey) == SUCCESS;
}
-
setData(dbValue, newValue);
- return tree.put(txn, dbKey, dbValue) == SUCCESS;
+ if (isDefined)
+ {
+ return tree.put(txn, dbKey, dbValue) == SUCCESS;
+ }
+ else if (tree.putNoOverwrite(txn, dbKey, dbValue) == SUCCESS)
+ {
+ return true;
+ }
+ // else retry due to phantom read: another thread inserted a record
}
- return false;
}
catch (DatabaseException e)
{
--
Gitblit v1.10.0