1

在 Jena 的 TDB 中,数据似乎是由一个“数据集”(由一个目录指定)组织的,它可以包含多个“命名图”。

关于查询此类数据的并发策略,我发现的唯一与并发相关的文档是 TDB 文档TDB Java API中的以下句子:

可以使用用于并发访问的多读取器或单写入器 (MRSW) 策略直接对数据集进行操作而无需事务。

但是,我不确定这种 MRSW 政策的粒度。它是在整个数据集上,还是在数据集中的单个命名图上?

编辑:更具体地说,我的要求是我想在没有任何读取操作的情况下对不同的命名图(每个线程写入不同的命名图)进行只写更新,这可能吗?还是我必须一次让一个线程更新。

4

3 回答 3

2

鉴于链接的文档说

可以使用用于并发访问的多读取器或单写入器 (MRSW) 策略直接对数据集进行操作而无需事务。

我希望,如果您有多个写入者将访问数据集,即使在不同的命名图中,您也应该使用事务。TDB Transactions上的文档说明了写事务:

一般模式是:

 dataset.begin(ReadWrite.WRITE) ;
 try {
   ...
   dataset.commit() ;
 } finally { 
   dataset.end() ; 
 }

并且那些对数据集的调用beginend与数据集相关联,而不是单独的命名图。

许多三元组存储(我认为 TDB 包含在其中)将命名图中的三元组视为四元组(通常称为四元组)。a b c命名图中的三元组可以与命名图中g1的三元组一起存储在同一个四元表中:d e fg2

g1 a b c
g2 d e f

然后这个代表单个数据集的四元表可以在四列中的任何一列上建立索引。在这种表示中,数据的命名图部分与数据的其余部分实际上并没有什么不同,因此命名图不提供任何对并发问题的隔离。实际上,由于通常 SPARQL 查询和更新可以读取或更新多个命名图,因此无法提前知道查询或更新将触及的命名图。

于 2013-09-23T21:25:15.637 回答
1

显然可以编写以下代码:

好的。显然可以编写以下代码:

Dataset dataset = TDBFactory.createDataset("demo");
Model model = dataset.getNamedModel("aModel");
try {
    model.enterCriticalSection(False);   //Write Lock

    // write triples to model

    model.commit();
    TDB.sync(model);
} finally {
    model.leaveCriticalSection();
}

据此,我认为同时写入不同的命名图应该没有任何问题。不过,这还没有经过测试。

于 2013-09-24T14:54:16.990 回答
1

同时写入同一数据集中的两个图是不安全的。

它似乎可以在没有事务的情况下工作,但它可能不安全。代码可能会检测到这一点并发出警告,但这是有保证的。

你应该使用事务。

当两个写入者尝试写入时,没有真正的并行写入(内部锁定以确保一切安全)。

如果您想强调写入,请考虑拥有两个数据集,然后创建一个通用的数据集(内存结构),其中包含来自每个单独数据集的模型。

在实践中,如果在具有一个磁盘的传统服务器上只有一条磁盘路径,那么真正的并行写入器可能不会比将事务写入同一数据库有太多优势。CPU + RAM 不是限制。

于 2013-09-24T16:13:50.650 回答