在向同一群集的不同实例中执行的JCR节点添加内容时,我一直在努力想出一个有效的解决方案。
已经解释here“当多个集群节点写入相同的节点时,必须首先锁定这些节点”。
我已经完成了,但我仍然得到如下所示的陈旧项目例外:
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)
我也遵循建议的方法来锁定节点here,(参见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");
请注意,这将同时在两个不同的实例(群集)上执行。
正如您在上面的代码中看到的那样,在我尝试保存刚刚添加到节点的锁之后,它会爆炸,但这是我之前共享的link i中所述的建议。 我理解为什么它会爆炸,这是因为两个实例试图在同一节点上添加锁。将锁添加到节点时,它会通过添加两个属性( jcr:lockOwner 和 jcr:lockIsDeep )来修改节点,因此如果实例1 添加锁定,然后实例2 添加锁定, instance1 尝试保存,然后您获得陈旧项目,因为实例2 通过添加a修改了节点锁定它...所以我如何防止这种情况发生?
非常感谢您的支持!
答案 0 :(得分:1)
我以某种方式找到了这个主题并检查了你的代码,你在这里错误的是你获得了一个基于会话的锁,因此你的群集存储库不知道锁,因为它没有应用于群集节点。
你应该做的是做以下事情:
session.getWorkspace().getLockManager().lock("/one", true, false, 5000, session.getUserID());
更多信息可在以下网址找到: https://wiki.apache.org/jackrabbit/Clustering#Concurrent_Write_Behavior 特别是在限制栏下。
答案 1 :(得分:0)
也许您可以尝试node.refresh(false)
强制节点刷新缓存并获得新的修改