我在单个框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();
有什么想法吗?可能有多个线程访问此代码,因为多个页面上的多个作者从创作的组件调用此代码。
谢谢你, 斯
答案 0 :(得分:3)
这是您在CQ5.5中经常看到的错误(并且每个版本向上都会减少)。此问题的根本原因是多个进程/服务在大致相同的时间跨度内修改相同的资源(通常使用不同的会话,有时甚至使用不同的用户)。
或许可以展示一个小例子。会话A和B都引用了资源X.会话A修改了X,保存和提交的一些属性,并被销毁。一切顺利。在A进行修改之前,会话B仍然有一个情况的快照,会话B进行修改,并且所有看起来都很好,直到它试图保存。此时,会话B检测到它无法提交其更改,因为它没有最新的节点状态。它已检测到其他一些会话对同一节点进行了更改。本质上,当前节点状态与会话A已完成的修改冲突并抛出ItemStale异常。此异常的原因是API不知道您是否希望保留A所做的更改,保留当前会话所做的更改并放弃A所做的更改,或合并它们。
此错误通常发生在长时间运行的会话和工作流/侦听器组合中。因此,建议尽量缩短会议时间,以尽可能地防止这种冲突。
解决这个问题的一种方法是在调用.save()之前调用session.refresh(keepChangesBoolean)。这指示当前会话检查其他会话所做的更新,并根据您提交的布尔标志处理它。但这并不能保证,因为在刷新和保存调用之间仍然可能,但是另一个会话也是如此。它只会降低发生此异常的几率。 处理此问题的另一种方法是从头开始重试。