用于并发访问的 Jackrabbit 存储库锁定

Posted

技术标签:

【中文标题】用于并发访问的 Jackrabbit 存储库锁定【英文标题】:Jackrabbit repository locking for concurrent access 【发布时间】:2013-12-07 09:41:18 【问题描述】:

我们有一个 REST 层和后端作为 Jackrabbit 实现。我们使用了默认设置的 TransientRepository。 当同时触发两个请求(仅用于读取节点)时,我们将面临以下错误:

:RepositoryLock.acquire(134)::Existing lock file tomcat/.lock 检测到。存储库未正确关闭。 javax.jcr.RepositoryException:存储库主目录 tomcat 似乎正在使用中,因为名为 .lock 的文件已被当前进程锁定。

jackrabbit wiki 页面:http://wiki.apache.org/jackrabbit/RepositoryLock 提到,当存储库已经在同一进程中打开但在另一个类加载器中(例如,在另一个 Web 应用程序中)时,会发生这种情况。在这种情况下,您需要确保在 Web 应用程序停止时关闭存储库。

我们使用以下代码来获取存储库和创建会话:

try 
Repository repository = new TransientRepository(REPO_CONFIG_FILE, REPO_HOME_DIR); 
session = repository.login(new SimpleCredentials(REPOSITORY_USERNAME, REPOSITORY_PASSWORD.toCharArray()));
 finally  
    if(session != null)
       session.logout();
     

上面的代码是针对 Jackrabbit 的每个操作的,所以每次操作后会话都会关闭。而且只有一个 Web 应用程序可以访问 Jackrabbit 存储库。

RepositoryLock 页面上给出的解决方案建议使用 Repository Server。这是这里唯一的解决方案,还是我在配置或编码时遗漏了什么?

【问题讨论】:

【参考方案1】:

也许你应该使用方法

loggedOut(SessionImpl 会话) 从打开的会话集中删除给定的会话。 这是特定于此存储库的 或者在应用程序侦听器中使用存储库服务器并通过 JNDI 访问它,以便您可以干净地启动/停止它?

【讨论】:

感谢您回答问题。我尝试使用 TransientRepository.loggedOut(sessionImpl) 方法并通过同时命中两个请求来测试它,但它仍然给出了 RepositoryLock 异常。我将评估拥有存储库服务器的另一个选项,但并发线程场景似乎很常见,因此我想知道是否有任何我遗漏的配置。

以上是关于用于并发访问的 Jackrabbit 存储库锁定的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 锁

如何通过 WebDAV 访问 Jackrabbit Oak 存储库?

Jackrabbit 和并发修改

Mysql:行锁 表锁 乐观锁 悲观锁 读锁 写锁

MySQL锁机制

数据库锁机制