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;
+ }
+
}