You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2007/06/29 14:56:35 UTC

svn commit: r551877 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core: XASessionImpl.java XAWorkspace.java version/XAVersionManager.java

Author: mreutegg
Date: Fri Jun 29 05:56:33 2007
New Revision: 551877

URL: http://svn.apache.org/viewvc?view=rev&rev=551877
Log:
JCR-962: Deadlocks in ConcurrentVersioningWithTransactionsTest

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java?view=diff&rev=551877&r1=551876&r2=551877
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java Fri Jun 29 05:56:33 2007
@@ -129,14 +129,21 @@
 
         /**
          * Create array that contains all resources that paricipate in this
-         * transactions. Because some resources depend on each other, there is
-         * also a workspace scoped lock resource inserted, that guards the
-         * entire transaction from deadlocks (see JCR-335)
+         * transactions. Some resources depend on each other, therefore you
+         * should only change the sequence if you know what you are doing!
+         *
+         * There are two artificial resources on the version manager (begin and
+         * end), which handle locking of the version manager. The begin resource
+         * acquires the write lock on the version manager in its prepare method,
+         * while the end resource releases the write lock in either commit or
+         * rollback. Please note that the write lock is only acquired if there
+         * is someting to commit by the version manager.
+         * For further information see JCR-335 and JCR-962.
          */
         txResources = new InternalXAResource[] {
-            ((XAWorkspace) wsp).getXAResourceBegin(),
+            versionMgr.getXAResourceBegin(),
             stateMgr, lockMgr, versionMgr,
-            ((XAWorkspace) wsp).getXAResourceEnd()
+            versionMgr.getXAResourceEnd()
         };
         stateMgr.setVirtualProvider(versionMgr);
     }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java?view=diff&rev=551877&r1=551876&r2=551877
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XAWorkspace.java Fri Jun 29 05:56:33 2007
@@ -21,20 +21,12 @@
 import org.apache.jackrabbit.core.state.XAItemStateManager;
 import org.apache.jackrabbit.core.state.LocalItemStateManager;
 
-import javax.jcr.NoSuchWorkspaceException;
-
 /**
  * Workspace extension that works in an XA environment.
  */
 public class XAWorkspace extends WorkspaceImpl {
 
     /**
-     * the name of the workspace info attribute in the transaction context
-     */
-    private static final String ATTR_NAME_WORKSPACE_INFO =
-            RepositoryImpl.WorkspaceInfo.class.getName();
-
-    /**
      * Protected constructor.
      *
      * @param wspConfig The workspace configuration
@@ -55,86 +47,4 @@
     protected LocalItemStateManager createItemStateManager(SharedItemStateManager shared) {
         return new XAItemStateManager(shared, this, rep.getItemStateCacheFactory());
     }
-
-    /**
-     * Returns an internal XAResource that is used at the beginning of the
-     * resources chain in {@link XASessionImpl#init()}. This resource will lock
-     * the workspace on <code>prepare</code>.
-     *
-     * @return an internal XAResource
-     */
-    protected InternalXAResource getXAResourceBegin() {
-        return new InternalXAResource() {
-            public void associate(TransactionContext tx) {
-            }
-
-            public void beforeOperation(TransactionContext tx) {
-            }
-
-            public void prepare(TransactionContext tx)
-                    throws TransactionException {
-                try {
-                    RepositoryImpl.WorkspaceInfo wspInfo =
-                            rep.getWorkspaceInfo(wspConfig.getName());
-                    wspInfo.lockAcquire();
-                    tx.setAttribute(ATTR_NAME_WORKSPACE_INFO, wspInfo);
-                } catch (NoSuchWorkspaceException e) {
-                    throw new TransactionException("Error while preparing for transaction", e);
-                }
-            }
-
-            public void commit(TransactionContext tx) {
-            }
-
-            public void rollback(TransactionContext tx) {
-            }
-
-            public void afterOperation(TransactionContext tx) {
-            }
-        };
-    }
-
-    /**
-     * Returns an internal XAResource that is used at the end of the
-     * resources chain in {@link XASessionImpl#init()}. This resource will unlock
-     * the workspace on <code>commit</code> or on <code>rollback</code>.
-     *
-     * @return an internal XAResource
-     */
-    protected InternalXAResource getXAResourceEnd() {
-        return new InternalXAResource() {
-            public void associate(TransactionContext tx) {
-            }
-
-            public void beforeOperation(TransactionContext tx) {
-            }
-
-            public void prepare(TransactionContext tx) {
-            }
-
-            public void commit(TransactionContext tx) {
-                RepositoryImpl.WorkspaceInfo wspInfo =
-                        (RepositoryImpl.WorkspaceInfo)
-                                tx.getAttribute(ATTR_NAME_WORKSPACE_INFO);
-                if (wspInfo != null) {
-                    wspInfo.lockRelease();
-                    tx.removeAttribute(ATTR_NAME_WORKSPACE_INFO);
-                }
-            }
-
-            public void rollback(TransactionContext tx) {
-                RepositoryImpl.WorkspaceInfo wspInfo =
-                        (RepositoryImpl.WorkspaceInfo)
-                                tx.getAttribute(ATTR_NAME_WORKSPACE_INFO);
-                if (wspInfo != null) {
-                    wspInfo.lockRelease();
-                    tx.removeAttribute(ATTR_NAME_WORKSPACE_INFO);
-                }
-            }
-
-            public void afterOperation(TransactionContext tx) {
-            }
-        };
-    }
-
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java?view=diff&rev=551877&r1=551876&r2=551877
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/XAVersionManager.java Fri Jun 29 05:56:33 2007
@@ -462,9 +462,6 @@
      * Delegate the call to our XA item state manager.
      */
     public void prepare(TransactionContext tx) throws TransactionException {
-        vMgr.acquireWriteLock();
-        vMgr.getSharedStateMgr().setNoLockHack(true);
-        vmgrLocked = true;
         ((XAItemStateManager) stateMgr).prepare(tx);
     }
 
@@ -476,12 +473,8 @@
      */
     public void commit(TransactionContext tx) throws TransactionException {
         ((XAItemStateManager) stateMgr).commit(tx);
-        vMgr.getSharedStateMgr().setNoLockHack(false);
-
         Map xaItems = (Map) tx.getAttribute(ITEMS_ATTRIBUTE_NAME);
         vMgr.itemsUpdated(xaItems.values());
-        vMgr.releaseWriteLock();
-        vmgrLocked = false;
     }
 
     /**
@@ -491,11 +484,6 @@
      */
     public void rollback(TransactionContext tx) {
         ((XAItemStateManager) stateMgr).rollback(tx);
-        if (vmgrLocked) {
-            vMgr.getSharedStateMgr().setNoLockHack(false);
-            vMgr.releaseWriteLock();
-            vmgrLocked = false;
-        }
     }
 
     /**
@@ -505,6 +493,80 @@
      */
     public void afterOperation(TransactionContext tx) {
         ((XAItemStateManager) stateMgr).afterOperation(tx);
+    }
+
+    /**
+     * Returns an {@link InternalXAResource} that acquires a write lock on the
+     * version manager in {@link InternalXAResource#prepare(TransactionContext)}
+     * if there are any version related items involved in this transaction.
+     *
+     * @return an internal XA resource.
+     */
+    public InternalXAResource getXAResourceBegin() {
+        return new InternalXAResource() {
+            public void associate(TransactionContext tx) {
+            }
+
+            public void beforeOperation(TransactionContext tx) {
+            }
+
+            public void prepare(TransactionContext tx) {
+                Map vItems = (Map) tx.getAttribute(ITEMS_ATTRIBUTE_NAME);
+                if (!vItems.isEmpty()) {
+                    vMgr.acquireWriteLock();
+                    vMgr.getSharedStateMgr().setNoLockHack(true);
+                    vmgrLocked = true;
+                }
+            }
+
+            public void commit(TransactionContext tx) {
+            }
+
+            public void rollback(TransactionContext tx) {
+            }
+
+            public void afterOperation(TransactionContext tx) {
+            }
+        };
+    }
+
+    /**
+     * Returns an {@link InternalXAResource} that releases the write lock on the
+     * version manager in {@link InternalXAResource#commit(TransactionContext)}
+     * or {@link InternalXAResource#rollback(TransactionContext)}.
+     *
+     * @return an internal XA resource.
+     */
+    public InternalXAResource getXAResourceEnd() {
+        return new InternalXAResource() {
+            public void associate(TransactionContext tx) {
+            }
+
+            public void beforeOperation(TransactionContext tx) {
+            }
+
+            public void prepare(TransactionContext tx) {
+            }
+
+            public void commit(TransactionContext tx) {
+                internalReleaseWriteLock();
+            }
+
+            public void rollback(TransactionContext tx) {
+                internalReleaseWriteLock();
+            }
+
+            public void afterOperation(TransactionContext tx) {
+            }
+
+            private void internalReleaseWriteLock() {
+                if (vmgrLocked) {
+                    vMgr.getSharedStateMgr().setNoLockHack(false);
+                    vMgr.releaseWriteLock();
+                    vmgrLocked = false;
+                }
+            }
+        };
     }
 
     //-------------------------------------------------------< implementation >