Jackrabbit Content Repository
  1. Jackrabbit Content Repository
  2. JCR-2712

Dirty Internal State on Transaction-Rollback during Global Transaction (container managed transaction)

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 1.6.2, 2.1.1
    • Fix Version/s: 2.2
    • Labels:
      None
    • Environment:
      Websphere 7 (IBM JRE 6), RessourceAdapter (Jackrabbit), Global Transaction (JTA)

      Description

      Running the following code inside an Global Transaction (JTA, container managed transaction) causes problems.

      Session session = getRepsoitorySession();
      Node rootNode = session.getRootNode();

      Node test = rootNode.addNode("test");
      test.addMixin(CTVRepositoryKonstanten.NODE_MIX_TYP_VERSION);
      session.save();
      throw new RuntimeException("testException");

      Everythink is fine, but if we execute it a second time we get an org.apache.jackrabbit.core.state.NoSuchItemStateException

      org.apache.jackrabbit.core.state.NoSuchItemStateException: b36d91bc-8687-428c-a767-2e087b13191a
      at org.apache.jackrabbit.core.state.SharedItemStateManager.getItemState(SharedItemStateManager.java:270)
      at org.apache.jackrabbit.core.state.LocalItemStateManager.getNodeState(LocalItemStateManager.java:107)
      at org.apache.jackrabbit.core.state.LocalItemStateManager.getItemState(LocalItemStateManager.java:172)
      at org.apache.jackrabbit.core.state.XAItemStateManager.getItemState(XAItemStateManager.java:260)
      at org.apache.jackrabbit.core.version.NodeStateEx.store(NodeStateEx.java:519)
      at org.apache.jackrabbit.core.version.NodeStateEx.store(NodeStateEx.java:489)
      at org.apache.jackrabbit.core.version.AbstractVersionManager.getParentNode(AbstractVersionManager.java:414)
      at org.apache.jackrabbit.core.version.AbstractVersionManager.createVersionHistory(AbstractVersionManager.java:357)
      at org.apache.jackrabbit.core.version.XAVersionManager.createVersionHistory(XAVersionManager.java:148)
      at org.apache.jackrabbit.core.version.AbstractVersionManager.getVersionHistory(AbstractVersionManager.java:273)
      at org.apache.jackrabbit.core.ItemImpl.initVersionHistories(ItemImpl.java:738)
      at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1097)
      at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:915)
      at org.apache.jackrabbit.jca.JCASessionHandle.save(JCASessionHandle.java:180)
      at de.continentale.repo.CTVRepository.erstelleDokument(CTVRepository.java:2267)

      We think that there is some internal state that is not cleaned up on rollback.
      Restarting the runtime (Application Server) "solved" this.

      May be there are some same causes like in: JCR-2503, JCR-2613

        Activity

        Hide
        Patrick Meyer added a comment - - edited

        In Jackrabbit Version 2.1.1 the same issue occurs

        Caused by: org.apache.jackrabbit.core.state.NoSuchItemStateException: 4ac5058c-060a-45ce-9d75-b5dbc0456c63
        at org.apache.jackrabbit.core.state.SharedItemStateManager.getItemState(SharedItemStateManager.java:274)
        at org.apache.jackrabbit.core.state.LocalItemStateManager.getNodeState(LocalItemStateManager.java:107)
        at org.apache.jackrabbit.core.state.LocalItemStateManager.getItemState(LocalItemStateManager.java:172)
        at org.apache.jackrabbit.core.state.XAItemStateManager.getItemState(XAItemStateManager.java:260)
        at org.apache.jackrabbit.core.version.NodeStateEx.store(NodeStateEx.java:741)
        at org.apache.jackrabbit.core.version.NodeStateEx.store(NodeStateEx.java:715)
        at org.apache.jackrabbit.core.version.InternalVersionManagerBase.getParentNode(InternalVersionManagerBase.java:547)
        at org.apache.jackrabbit.core.version.InternalVersionManagerBase.internalCreateVersionHistory(InternalVersionManagerBase.java:411)
        at org.apache.jackrabbit.core.version.InternalXAVersionManager.createVersionHistory(InternalXAVersionManager.java:167)
        at org.apache.jackrabbit.core.version.InternalVersionManagerBase.getVersionHistory(InternalVersionManagerBase.java:322)
        at org.apache.jackrabbit.core.version.InternalXAVersionManager.getVersionHistory(InternalXAVersionManager.java:58)
        at org.apache.jackrabbit.core.ItemImpl.initVersionHistories(ItemImpl.java:778)
        at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1119)
        at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:920)
        at org.apache.jackrabbit.jca.JCASessionHandle.save(JCASessionHandle.java:184)

        Show
        Patrick Meyer added a comment - - edited In Jackrabbit Version 2.1.1 the same issue occurs Caused by: org.apache.jackrabbit.core.state.NoSuchItemStateException: 4ac5058c-060a-45ce-9d75-b5dbc0456c63 at org.apache.jackrabbit.core.state.SharedItemStateManager.getItemState(SharedItemStateManager.java:274) at org.apache.jackrabbit.core.state.LocalItemStateManager.getNodeState(LocalItemStateManager.java:107) at org.apache.jackrabbit.core.state.LocalItemStateManager.getItemState(LocalItemStateManager.java:172) at org.apache.jackrabbit.core.state.XAItemStateManager.getItemState(XAItemStateManager.java:260) at org.apache.jackrabbit.core.version.NodeStateEx.store(NodeStateEx.java:741) at org.apache.jackrabbit.core.version.NodeStateEx.store(NodeStateEx.java:715) at org.apache.jackrabbit.core.version.InternalVersionManagerBase.getParentNode(InternalVersionManagerBase.java:547) at org.apache.jackrabbit.core.version.InternalVersionManagerBase.internalCreateVersionHistory(InternalVersionManagerBase.java:411) at org.apache.jackrabbit.core.version.InternalXAVersionManager.createVersionHistory(InternalXAVersionManager.java:167) at org.apache.jackrabbit.core.version.InternalVersionManagerBase.getVersionHistory(InternalVersionManagerBase.java:322) at org.apache.jackrabbit.core.version.InternalXAVersionManager.getVersionHistory(InternalXAVersionManager.java:58) at org.apache.jackrabbit.core.ItemImpl.initVersionHistories(ItemImpl.java:778) at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:1119) at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:920) at org.apache.jackrabbit.jca.JCASessionHandle.save(JCASessionHandle.java:184)
        Hide
        Patrick Meyer added a comment -

        The problem seems to be that ItemStates that are stored in InternalXAVersionmanager are not rollbacked until the boolean vmgrLocked is true.

        see Line 624 of InternalXAVersionManager last changed by mreutegg in Revision 637865
        http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalXAVersionManager.java?view=markup

        This variable can only be true after an prepare Call to the XASession (First Call in 2 Phase Commit) . But our "rollback trigger" occurs before the call of XASession.prepare.
        see Line 654 of InternalXAVersionManager

        The changeset http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalXAVersionManager.java?r1=637864&r2=637865& checks logging before commit. I think checking vmgrLocked in rollback case is wrong.

        Does it have any other side-effect if we remove the check of vmgrLocked in rollback case?
        Revision 637865 was for fixing JCR-1480

        Show
        Patrick Meyer added a comment - The problem seems to be that ItemStates that are stored in InternalXAVersionmanager are not rollbacked until the boolean vmgrLocked is true. see Line 624 of InternalXAVersionManager last changed by mreutegg in Revision 637865 http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalXAVersionManager.java?view=markup This variable can only be true after an prepare Call to the XASession (First Call in 2 Phase Commit) . But our "rollback trigger" occurs before the call of XASession.prepare. see Line 654 of InternalXAVersionManager The changeset http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/version/InternalXAVersionManager.java?r1=637864&r2=637865& checks logging before commit. I think checking vmgrLocked in rollback case is wrong. Does it have any other side-effect if we remove the check of vmgrLocked in rollback case? Revision 637865 was for fixing JCR-1480
        Hide
        Sebastian Sickelmann added a comment -

        I think this bug relates to jackrabbit core. Because the cause of the bug is in java.org.apache.jackrabbit.core.version.InternalXAVersionManager

        Show
        Sebastian Sickelmann added a comment - I think this bug relates to jackrabbit core. Because the cause of the bug is in java.org.apache.jackrabbit.core.version.InternalXAVersionManager
        Hide
        Dominik Klaholt added a comment - - edited

        Executing the following method within XATest.java ( http://svn.apache.org/repos/asf/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java ) provokes the error as well (the error does not seem to occur every time, though -> that's why the for-loop does so many iterations):

        public void testXAVersionManagerProblem() throws Exception {
        Session session = null;
        try {
        session = getHelper().getSuperuserSession();
        if (session.getRootNode().hasNode("testNode"))

        { session.getRootNode().getNode("testNode").remove(); session.save(); }

        UserTransaction utx;
        for (int i = 0; i < 50; i++)

        { utx = new UserTransactionImpl(session); utx.begin(); session.getRootNode().addNode("testNode").addMixin(NodeType.MIX_VERSIONABLE); session.save(); utx.rollback(); }

        } finally {
        if (session != null)

        { session.logout(); }

        }
        }

        Show
        Dominik Klaholt added a comment - - edited Executing the following method within XATest.java ( http://svn.apache.org/repos/asf/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/XATest.java ) provokes the error as well (the error does not seem to occur every time, though -> that's why the for-loop does so many iterations): public void testXAVersionManagerProblem() throws Exception { Session session = null; try { session = getHelper().getSuperuserSession(); if (session.getRootNode().hasNode("testNode")) { session.getRootNode().getNode("testNode").remove(); session.save(); } UserTransaction utx; for (int i = 0; i < 50; i++) { utx = new UserTransactionImpl(session); utx.begin(); session.getRootNode().addNode("testNode").addMixin(NodeType.MIX_VERSIONABLE); session.save(); utx.rollback(); } } finally { if (session != null) { session.logout(); } } }
        Hide
        Jukka Zitting added a comment -

        Thanks for the accurate review of the problem and especially for the test case that made it easy to reproduce and fix this!

        It seems to me that the problem is not that much the vmgrLocked check in the rollback() case, but rather the fact that the code calling rollback() has not called prepare() first. This is the case for the UserTransactionImpl utility class in Jackrabbit and apparently also in some transaction managers. However the InternalXAVersionManager class expects that a commit() or a rollback() can only happen after prepare() has already been called.

        To better handle such situations I modified the InternalXAVersionManager to always make sure that the transaction is prepared before a commit() or a rollback() is performed. See revision 1000385 for this fix.

        Show
        Jukka Zitting added a comment - Thanks for the accurate review of the problem and especially for the test case that made it easy to reproduce and fix this! It seems to me that the problem is not that much the vmgrLocked check in the rollback() case, but rather the fact that the code calling rollback() has not called prepare() first. This is the case for the UserTransactionImpl utility class in Jackrabbit and apparently also in some transaction managers. However the InternalXAVersionManager class expects that a commit() or a rollback() can only happen after prepare() has already been called. To better handle such situations I modified the InternalXAVersionManager to always make sure that the transaction is prepared before a commit() or a rollback() is performed. See revision 1000385 for this fix.

          People

          • Assignee:
            Jukka Zitting
            Reporter:
            Sebastian Sickelmann
          • Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development