为什么jar文件中出现TDB2“已锁定”问题?

问题描述

我正在开发一个Apache Jena应用程序。当我从Intellij IDE运行代码时,它可以正常工作,但是如果我生成一个jar文件并在终端中运行jar文件,它将无法正常工作。

我得到的错误:

Uncaught exeption ! : org.apache.jena.dboe.base.file.AlreadyLocked: Failed to get a lock: file='/home/iam/OneDrive/Internship/current_data/myTDB/tdb.lock': Lock already held

我正在使用:

  • Apache jena(3.15.0)。 (TDB2)
  • 6.5级
  • JVM:11.0.8(Ubuntu 11.0.8 + 10-post-Ubuntu-0ubuntu120.04)

解决方法

TDB特定的锁定问题

我会以TDB FAQs作为第一个参考:

此异常是TDB自动防止多JVM使用的结果,如前所述,我可以在多个应用程序之间共享TDB数据集吗?问题:TDB数据库只能由单个JVM安全地使用,否则可能会发生数据损坏。从1.1.0开始,TDB会自动强制实施此限制,并且如果您尝试访问从另一个JVM访问的数据库,则会出现此异常。

基本上,您不能同时从两个进程中打开相同的TDB数据库位置。

关于您的特定情况下发生的事情:

  1. 您可以从IntelliJ内部运行一些代码来访问TDB数据库。假设IntelliJ没有派生新的JVM,则会创建锁定文件,然后该锁定文件将与IntelliJ进程本身关联。
    或者,如果IntelliJ正在分叉新流程,那么您/不是 完成操作后,明确停止该正在运行的进程。
  2. 然后,您尝试并运行构建的JAR文件。尝试打开TDB数据库,发现存在锁定文件并指向活动的IntelliJ进程,因此拒绝访问数据库。

您最有可能需要退出并重新启动IntelliJ,因为该进程(或子进程)将成为锁持有者。然后,您需要确保从IntelliJ内部运行的所有代码都作为新进程生成,并且每当您要分别测试构建的JAR时,都必须停止该进程。

另一种可能的方法是使TDB数据库位置可配置,以便在IntelliJ中进行测试时与运行JAR文件时使用不同的位置。这样,您就可以避免两个进程争用数据库锁的可能性,因为它们将使用单独的数据库。

文件系统特定的锁定问题

我还注意到您的数据库似乎位于OneDrive位置-/home/iam/OneDrive/Internship/current_data/myTDB/tdb.lock-此处还可能发生文件系统问题。

  1. 由于OneDrive不一定将所有文件存储在本地,因此用于将其安装到系统上的文件系统实际上可能不支持该位置的锁定。尽管您的代码确实可以在IntelliJ内部运行,这一事实似乎表明事实并非如此。但是,您可以尝试使用本地驱动器上肯定存在的数据库位置来排除此情况。
  2. 该位置被其他进程隐式锁定(也许是OneDrive本身,也许是IntelliJ,或完全是其他东西)

对于2,这似乎是您所遇到的问题,您可以尝试找出持有该锁的原因,例如How to list processes locking file找出导致其锁定的其他进程,并进行进一步调查。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...