在向在同一集群的不同实例中执行的JCR节点添加内容时,我一直在努力想出一个可行的解决方案。
这里已经解释过“当多个集群节点写入相同的节点时,必须首先锁定这些节点”。
我已经这样做了,但仍然有一些过时的例外情况,如下所示:
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)我还遵循了关于如何锁定节点这里 (参见17.10锁和事务)的建议方法。
这里是我的代码的简化版本,当涉及到锁定过程时
session.getRootNode().addNode("one").addMixin("mix:lockable");
session.save();
session.getWorkspace().getLockManager().lock("/one", true, true, 5000, session.getUserID());
session.save();// usually it explodes here
session.getNode("/one").addNode("two").addMixin("mix:lockable");
session.save();
session.getWorkspace().getLockManager().unlock("/one");请注意,这将在两个不同的实例(集群)上同时执行。
正如您在上面的代码中所看到的,在我试图保存刚才添加到节点的锁之后,它会爆炸,但是这是我前面共享的链接中的建议。我理解它为什么会爆炸,这是因为两个实例试图在同一个节点上添加锁。当一个锁被添加到一个节点时,它通过添加两个属性(jcr:lockOwner和jcr::)来修改节点,因此如果实例1添加了锁,那么实例2添加了锁,而instance1试图保存,则会得到过时的项,因为instance 2通过向节点添加锁来修改节点.那我怎么才能防止这种情况发生呢?
非常感谢您的支持!
发布于 2016-09-22 12:16:24
我以某种方式找到了这个主题,并检查了您的代码,这里您的错误是您正在获取一个基于会话的锁,因此您的集群存储库没有想到锁,因为它不应用于集群节点。
相反,您应该做的是做以下工作:
session.getWorkspace().getLockManager().lock("/one", true, false, 5000, session.getUserID());更多信息可以在:行为中找到,特别是在限制栏中。
发布于 2016-09-21 07:25:08
也许您可以尝试使用node.refresh(false)来强制节点刷新缓存并获得新的修改。
https://stackoverflow.com/questions/39609372
复制相似问题