You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2011/09/22 11:28:10 UTC

svn commit: r1174017 - in /jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: NodeImpl.java state/LocalItemStateManager.java state/SessionItemStateManager.java

Author: jukka
Date: Thu Sep 22 09:28:09 2011
New Revision: 1174017

URL: http://svn.apache.org/viewvc?rev=1174017&view=rev
Log:
JCR-2272: Errors during concurrent session import of nodes with same UUIDs

Avoid the check for an existing id in NodeImpl.makePersistent().
Also fix a problem with cases where a node with a specific UUID
is both removed and added within the same transient space.

Modified:
    jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
    jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
    jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java

Modified: jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java?rev=1174017&r1=1174016&r2=1174017&view=diff
==============================================================================
--- jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java Thu Sep 22 09:28:09 2011
@@ -848,30 +848,8 @@ public class NodeImpl extends ItemImpl i
         }
 
         NodeState transientState = data.getNodeState();
+        NodeState localState = stateMgr.makePersistent(transientState);
 
-        NodeState localState = (NodeState) transientState.getOverlayedState();
-        if (localState == null) {
-            // this node is 'new'
-            try {
-                localState = stateMgr.createNew(
-                        transientState.getNodeId(),
-                        transientState.getNodeTypeName(),
-                        transientState.getParentId());
-                transientState.connect(localState);
-            } catch (ItemStateException e) {
-                throw new RepositoryException(e);
-            }
-        }
-
-        synchronized (localState) {
-            // copy state from transient state:
-            localState.copy(transientState, true);
-            // make state persistent
-            stateMgr.store(localState);
-        }
-
-        // tell state manager to disconnect item state
-        stateMgr.disconnectTransientItemState(transientState);
         // swap transient state with local state
         data.setState(localState);
         // reset status

Modified: jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java?rev=1174017&r1=1174016&r2=1174017&view=diff
==============================================================================
--- jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java (original)
+++ jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java Thu Sep 22 09:28:09 2011
@@ -272,7 +272,8 @@ public class LocalItemStateManager
         changeLog.added(state);
         state.setContainer(this);
 
-        if (nonRandomId && sharedStateMgr.hasItemState(id)) {
+        if (nonRandomId && !changeLog.deleted(id)
+                && sharedStateMgr.hasItemState(id)) {
             throw new InvalidItemStateException(
                     "Node " + id + " already exists");
         }
@@ -281,6 +282,38 @@ public class LocalItemStateManager
     }
 
     /**
+     * Returns the local node state below the given transient one. If given
+     * a fresh new node state, then a new local state is created and added
+     * to the change log.
+     *
+     * @param transientState transient state
+     * @return local node state
+     * @throws RepositoryException if the local state could not be created
+     */
+    public NodeState getOrCreateLocalState(NodeState transientState)
+            throws RepositoryException {
+        NodeState localState = (NodeState) transientState.getOverlayedState();
+        if (localState == null) {
+            // The transient node state is new, create a new local state
+            localState = new NodeState(
+                    transientState.getNodeId(),
+                    transientState.getNodeTypeName(),
+                    transientState.getParentId(),
+                    ItemState.STATUS_NEW,
+                    false);
+            changeLog.added(localState);
+            localState.setContainer(this);
+            try {
+                transientState.connect(localState);
+            } catch (ItemStateException e) {
+                // should never happen
+                throw new RepositoryException(e);
+            }
+        }
+        return localState;
+    }
+
+    /**
      * {@inheritDoc}
      */
     public PropertyState createNew(Name propName, NodeId parentId)

Modified: jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=1174017&r1=1174016&r2=1174017&view=diff
==============================================================================
--- jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java (original)
+++ jackrabbit/branches/JCR-2272/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java Thu Sep 22 09:28:09 2011
@@ -959,4 +959,31 @@ public class SessionItemStateManager
         }
     }
 
+    /**
+     * Pushes the given transient state to the change log so it'll be
+     * persisted when the change log is committed. The transient state
+     * is replaced with the local state that has been pushed to the
+     * change log.
+     *
+     * @param transientState transient state
+     * @return the local state to be persisted
+     * @throws RepositoryException if the transiet state can not be persisted
+     */
+    public NodeState makePersistent(NodeState transientState)
+            throws RepositoryException {
+        NodeState localState = stateMgr.getOrCreateLocalState(transientState);
+
+        synchronized (localState) {
+            // copy state from transient state:
+            localState.copy(transientState, true);
+            // make state persistent
+            store(localState);
+        }
+
+        // disconnect the transient item state
+        disconnectTransientItemState(transientState);
+
+        return localState;
+    }
+
 }