多集群环境中的 JCR 锁定

JCR locking on multi clustered environment

在将内容添加到在同一集群的不同实例中执行的 JCR 节点时,我一直在努力想出一个可行的解决方案。

已解释 here "when multiple cluster nodes write to the same nodes, those nodes must be locked first"。

我已经做到了,但我仍然收到如下所示的陈旧项目异常:

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 中提出的建议。 我明白它为什么会爆炸,这是因为两个实例试图在同一个节点上添加锁。将锁添加到节点时,它会通过添加两个属性(jcr:lockOwnerjcr:lockIsDeep)来修改节点,因此如果 instance 1 添加了锁然后 instance 2 添加了锁,并且 instance1 试图保存然后你得到陈旧的项目,因为实例 2 通过向其添加锁修改了节点...那么我该如何防止这种情况发生?

非常感谢您的支持!

也许你可以尝试 node.refresh(false) 来强制节点刷新他的缓存并获得新的修改

我以某种方式找到了这个主题并检查了你的代码,你在这里错了什么是你正在获取基于会话的锁因此你的集群存储库不知道锁,因为它没有应用于集群节点。

您应该做的是执行以下操作:

session.getWorkspace().getLockManager().lock("/one", true, false, 5000, session.getUserID());

可以在以下位置找到更多信息: https://wiki.apache.org/jackrabbit/Clustering#Concurrent_Write_Behavior 特别是在限制栏下。