3

在我的 Apache Tomcat 服务器上,我有一个 OpenRDF Sesame Triplestore 来处理与用户和文档相关的 RDF 三元组以及此类实体之间的双向链接:

http://local/id/doc/123456 myvocabulary:title "EU Economy"
http://local/id/doc/456789 myvocabulary:title "United States Economy"

http://local/id/user/JohnDoe myvocabulary:email "john@doe.com"
http://local/id/user/JohnDoe myvocabylary:hasWritten http://local/id/doc/123456

这个三重状态是用户 John Doe 与电子邮件“john@doe.com”撰写了“欧盟经济”一书。

在多个客户端上运行的 Java 应用程序通过 HTTPRespository 使用此类服务​​器来插入/更新/删除此类三元组。

问题来自并发连接。如果一个 Java 客户端删除了书“456789”并且另一个客户端同时将同一本书链接到“John Doe”,那么可能会出现“John Doe”链接到不再存在的书的情况。

为了尝试找到解决方案,我进行了两次交易。第一个是(T1):

  • (a) 检查书籍 ID 是否存在(即“456789”)。

  • (b) 如果是,将给定的个人资料(即“JohnDoe”)链接到这本书。

  • (c) 如果否,则返回错误。

第二个是(T2):

  • (d) 按 id 删除图书(即“456789”)。

问题是如果序列是 (T1,a) (T2,d) (T1,b) (T1,c),那么再次存在一致性问题。

我的问题是:如何处理锁定(如 MySQL FOR UPDATE 或 GET_LOCK)以正确隔离此类事务与 sesame ?

4

1 回答 1

2

Sesame 的旧版本(2.7.x 和更早版本)不支持通过 HTTP 进行事务隔离。在 HTTP 连接中,事务只是在客户端一起批量操作,并没有从服务器获取锁,所以在这种情况下没有办法控制隔离。

因此,在较旧的 Sesame 版本中处理此问题的唯一方法是在查询中保持稳健,而不是依赖完整的数据一致性(无论如何,这在无模式/半结构化数据范例中有点奇怪)。例如,在这种特殊情况下,请确保当您查询链接到配置文件的图书时,图书数据确实存在 - 不要仅仅依赖参考。

然而,在 Sesame 2.8 和更新版本中,可以通过 HTTP 获得完整的事务隔离支持,并且还可以基于每个事务对确切的事务隔离级别进行额外的控制。锁定方案取决于您使用的特定三元存储实现。

Sesame 的原生存储使用乐观锁定,这意味着它假定事务能够进行它想要的更新,并在发生冲突时抛出异常。为事务设置隔离级别控制存储如何处理并发事务的锁定。Sesame Programmers 手册包含有关事务处理和可用隔离级别的更多详细信息。本机存储上事务的默认隔离级别是SNAPSHOT_READ.

至于您的示例事务:在默认隔离级别下,T1 和 T2 都为他们的查询观察商店的一致快照,并且您绘制它的顺序是:T1 看到这本书存在,因此将其添加到配置文件中,并且T2 可以删除它。最终结果将是配置文件链接到不存在的书籍 - 但实际上,这在技术上并非不一致,因为 T2 不会对特定书籍是否在配置文件中使用进行任何验证。无论您使用哪种事务隔离级别,如果在您的场景中 T2 在之后执行T1,最终结果将是一个不存在的书的链接。如果要确保不会陷入这种情况,则需要扩展 T2 以检查即将删除的图书是否未链接到配置文件,并设置隔离级别SNAPSHOTSERIALIZABLE.

于 2014-06-22T21:14:43.050 回答