是否可以同时写入相同的数据集文件,但可以写入不同的命名图形(每个线程写入不同的命名图形)?

时间:2013-09-23 21:11:27

标签: multithreading concurrency jena tdb

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

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

  

可以直接对数据集执行操作,而无需使用Multiple Reader或Single Writer(MRSW)策略进行并发访问。

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

编辑:更具体地说,我的要求是我想对不同的命名图形进行只写更新(每个线程写入不同的命名图形)而不进行任何读取操作,是否可能?或者我必须一次更新一个线程。

3 个答案:

答案 0 :(得分:2)

鉴于链接文档说

  

可以直接在数据集上执行操作,而无需使用多读取器或单个写入器(MRSW)策略进行并发访问。

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

  

一般模式是:

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

这些对beginend的调用与数据集关联,而不是与单个命名图关联。

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

g1 a b c
g2 d e f

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

答案 1 :(得分: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();
}

据此,我认为同时写入不同的命名图表应该没有任何问题。但仍未对此进行测试。

答案 2 :(得分:1)

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

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

您应该使用交易。

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

如果你想强调写,考虑有两个数据集,然后用每个独立数据集中的模型创建一个通用的数据集(内存结构)。

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