Index: src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java =================================================================== --- src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (revision 1352099) +++ src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (working copy) @@ -787,6 +787,24 @@ ISMLocking.ReadLock readLock = null; try { + + synchronized (SharedItemStateManager.this) { + // add all ids of new item states to the + // currentlyLoading set to prevent reads + // from other sessions while lock is downgraded + // to a read lock and shared.persisted() is + // in progress + for (ItemState added : shared.addedStates()) { + boolean wasAdded = currentlyLoading.add(added.getId()); + // the ISMLocking contract ensures that at + // this point no other thread is reading items + // that are referenced in the shared ChangeLog. + // that is, currentlyLoading must always return + // true here + assert (wasAdded); + } + } + // downgrade to read lock readLock = writeLock.downgrade(); writeLock = null; @@ -795,6 +813,13 @@ // JCR-2171: This must happen after downgrading the lock! shared.persisted(); + synchronized (SharedItemStateManager.this) { + for (ItemState added : shared.addedStates()) { + currentlyLoading.remove(added.getId()); + } + SharedItemStateManager.this.notifyAll(); + } + /* notify virtual providers about node references */ for (int i = 0; i < virtualNodeReferences.length; i++) { ChangeLog virtualRefs = virtualNodeReferences[i]; @@ -1708,9 +1733,10 @@ /** * Identifiers of the item states that are currently being loaded from - * the underlying persistence manager. Used exclusively by the - * {@link #getNonVirtualItemState(ItemId)} method to prevent two threads - * from concurrently loading the same items. + * the underlying persistence manager. Used by + * {@link #getNonVirtualItemState(ItemId)} and + * {@link Update#end()} method to prevent two threads from concurrently + * loading the same items. */ private final Set currentlyLoading = new HashSet();