javax.jcr.InvalidItemStateException:无法保存项目

时间:2016-08-10 16:01:00

标签: cq5 aem jcr sling jackrabbit

我在单个框cq5作者环境中遇到异常。

javax.jcr.InvalidItemStateException: Item cannot be saved 
because node property has been modified externally

更多例外情况:

Caused by: javax.jcr.InvalidItemStateException: Unable to update a stale item: item.save()
    at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:262)
    at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
    at org.apache.jackrabbit.core.ItemImpl.perform(ItemImpl.java:91)
    at org.apache.jackrabbit.core.ItemImpl.save(ItemImpl.java:329)
    at org.apache.jackrabbit.core.session.SessionSaveOperation.perform(SessionSaveOperation.java:65)
    at org.apache.jackrabbit.core.session.SessionState.perform(SessionState.java:216)
    at org.apache.jackrabbit.core.SessionImpl.perform(SessionImpl.java:361)
    at org.apache.jackrabbit.core.SessionImpl.save(SessionImpl.java:812)
    at com.day.crx.core.CRXSessionImpl.save(CRXSessionImpl.java:142)
    at org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProvider.commit(JcrResourceProvider.java:511)
    ... 215 more
Caused by: org.apache.jackrabbit.core.state.StaleItemStateException: 3bec1cb7-9276-4bed-a24e-0f41bb3cf5b7/{}ssn has been modified externally
    at org.apache.jackrabbit.core.state.SharedItemStateManager$Update.begin(SharedItemStateManager.java:679)
    at org.apache.jackrabbit.core.state.SharedItemStateManager.beginUpdate(SharedItemStateManager.java:1507)
    at org.apache.jackrabbit.core.state.SharedItemStateManager.update(SharedItemStateManager.java:1537)
    at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:400)
    at org.apache.jackrabbit.core.state.XAItemStateManager.update(XAItemStateManager.java:354)
    at org.apache.jackrabbit.core.state.LocalItemStateManager.update(LocalItemStateManager.java:375)
    at org.apache.jackrabbit.core.state.SessionItemStateManager.update(SessionItemStateManager.java:275)
    at org.apache.jackrabbit.core.ItemSaveOperation.perform(ItemSaveOperation.java:258)

以下是代码示例:

adminResourceResolver = resourceResolverFactory
                .getAdministrativeResourceResolver(null);
Resource fundPageResource = adminResourceResolver.getResource(page
                .getPath() + "/jcr:content");
ModifiableValueMap homePageResourceProperties = fundPageResource
                .adaptTo(ModifiableValueMap.class);
homePageResourceProperties.put("ssn",(person.getSsn());

adminResourceResolver.commit();

有什么想法吗?可能有多个线程访问此代码,因为多个页面上的多个作者从创作的组件调用此代码。

谢谢你, 斯

1 个答案:

答案 0 :(得分:3)

这是您在CQ5.5中经常看到的错误(并且每个版本向上都会减少)。此问题的根本原因是多个进程/服务在大致相同的时间跨度内修改相同的资源(通常使用不同的会话,有时甚至使用不同的用户)。

或许可以展示一个小例子。会话A和B都引用了资源X.会话A修改了X,保存和提交的一些属性,并被销毁。一切顺利。在A进行修改之前,会话B仍然有一个情况的快照,会话B进行修改,并且所有看起来都很好,直到它试图保存。此时,会话B检测到它无法提交其更改,因为它没有最新的节点状态。它已检测到其他一些会话对同一节点进行了更改。本质上,当前节点状态与会话A已完成的修改冲突并抛出ItemStale异常。此异常的原因是API不知道您是否希望保留A所做的更改,保留当前会话所做的更改并放弃A所做的更改,或合并它们。

此错误通常发生在长时间运行的会话和工作流/侦听器组合中。因此,建议尽量缩短会议时间,以尽可能地防止这种冲突。

解决这个问题的一种方法是在调用.save()之前调用session.refresh(keepChangesBoolean)。这指示当前会话检查其他会话所做的更新,并根据您提交的布尔标志处理它。但这并不能保证,因为在刷新和保存调用之间仍然可能,但是另一个会话也是如此。它只会降低发生此异常的几率。 处理此问题的另一种方法是从头开始重试。