You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2015/07/15 11:57:31 UTC
svn commit: r1691159 -
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
Author: mreutegg
Date: Wed Jul 15 09:57:31 2015
New Revision: 1691159
URL: http://svn.apache.org/r1691159
Log:
OAK-3103: Stale document in MongoDocumentStore cache
- Use update operation instead of findAndModify for conditional update
- Unconditional update the cache when the before document is known
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java?rev=1691159&r1=1691158&r2=1691159&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java Wed Jul 15 09:57:31 2015
@@ -798,16 +798,11 @@ public class MongoDocumentStore implemen
QueryBuilder query = createQueryForUpdate(updateOp.getId(),
updateOp.getConditions());
query.and(Document.MOD_COUNT).is(modCount);
- DBObject fields = new BasicDBObject();
- // return _id only
- fields.put("_id", 1);
-
- DBObject oldNode = dbCollection.findAndModify(query.get(), fields,
- null /*sort*/, false /*remove*/, update, false /*returnNew*/,
- false /*upsert*/);
- if (oldNode != null) {
+
+ WriteResult result = dbCollection.update(query.get(), update);
+ if (result.getN() > 0) {
// success, update cached document
- applyToCache(collection, cachedDoc, updateOp);
+ putToCache(collection, cachedDoc, updateOp);
// return previously cached document
return cachedDoc;
}
@@ -821,9 +816,11 @@ public class MongoDocumentStore implemen
return null;
}
T oldDoc = convertFromDBObject(collection, oldNode);
- applyToCache(collection, oldDoc, updateOp);
if (oldDoc != null) {
+ putToCache(collection, oldDoc, updateOp);
oldDoc.seal();
+ } else {
+ applyToCache(collection, null, updateOp);
}
return oldDoc;
} catch (Exception e) {
@@ -1258,6 +1255,30 @@ public class MongoDocumentStore implemen
}
}
+ /**
+ * Unconditionally puts a document into the cache if {@code collection} is
+ * {@link Collection#NODES}. The document put into the cache is
+ * {@code oldDoc} with the {@code updateOp} applied. This method does not
+ * acquire a lock from {@link #locks}! The caller must ensure a lock is held
+ * for the given document.
+ *
+ * @param collection the collection where oldDoc belongs to.
+ * @param oldDoc how the document looked before the update.
+ * @param updateOp the update just applied to the document.
+ */
+ private <T extends Document> void putToCache(@Nonnull Collection<T> collection,
+ @Nonnull T oldDoc,
+ @Nonnull UpdateOp updateOp) {
+ if (collection == Collection.NODES) {
+ CacheValue key = new StringValue(oldDoc.getId());
+ NodeDocument newDoc = (NodeDocument) collection.newDocument(this);
+ oldDoc.deepCopy(newDoc);
+ UpdateUtils.applyChanges(newDoc, updateOp, comparator);
+ newDoc.seal();
+ nodesCache.put(key, newDoc);
+ }
+ }
+
@Nonnull
private static QueryBuilder createQueryForUpdate(String key,
Map<Key, Condition> conditions) {