我正在做一项学术研究,试图开发一种编程工具,帮助实现细粒度锁定函数,用于维护树状数据结构的并发程序。
例如,程序员可能会编写一些函数来接收树根节点并修改树(通过遍历某些路由并添加/删除节点),该工具将帮助他找到代码中应该锁定节点的位置以及可以释放它们的位置 - 因此函数可以在同一棵树上并发执行。
我正在寻找一些现实生活中的代码示例,其中使用了这种细粒度锁定,或者可以使用它来提高性能,但程序员懒得实现它(例如,他在函数调用期间锁定了整个树而不释放无用的节点)。
我读了关于JCR和Jackrabbit的文章,它使用树形数据库,并找到了一篇文章,解释了如何在JCR中锁定节点(但没有示例):http://www.day.com/specs/jcr/2.0/17_Locking.html
我在数据库方面的背景非常小,当涉及到 Jackrabbit 数据库和并发性时,我不完全了解什么是允许的,什么是不允许的。不允许从 2 个线程访问同一节点,但是不同的存储库呢?如果 2 个不同的客户端尝试访问同一个节点(例如,一个尝试删除它,另一个尝试修改它 - session.save() 会失败吗?
谢谢奥 伦
首先,不要混淆数据库/jackrabbit/locking。Jackrabbit实现了自己的锁定,数据库也是如此。
Jackrabbit允许您使用LockManager.lock()
锁定节点。将 isDeep
参数设置为 true 意味着下面的所有节点也将被锁定。锁定的节点可以由另一个会话读取,但不能修改。
从技术上讲,如果 2 个线程使用相同的会话,它们可以编辑同一个节点,但这相当危险,可能应该避免。
如果一个节点可能被 2 个并发会话修改,则应始终锁定该节点。哪个会话最后到达那里应该等待锁被释放。如果不锁定,则至少有一个会话将引发异常。
我不确定您从不同存储库访问节点是什么意思。一个节点只能属于一个存储库。如果您的意思是让 2 个 jackrabbit 实例访问同一个数据库,那么也应该避免这种情况,或者您应该考虑使用集群。
实施锁定时,它将取决于您的设计和要求。如果您只有一个会话,则锁定是没有意义的,反之亦然。是锁定节点还是子树将取决于数据所代表的内容。例如,如果节点表示一个文件夹,则您可能希望仅锁定节点,而不是整个子树。如果子树表示复杂文档,那么您可能希望锁定子树。
至于锁定整棵树,我希望我不会遇到这样做的人!