在Jena的TDB中,似乎数据是由“数据集”(由目录指定)组织的,该数据集可以包含多个“命名图”。
关于查询此类数据的并发策略,我发现的与并发相关的唯一文档是TDB文档TDB Java API中的以下句子:
可以直接对数据集执行操作,而无需使用Multiple Reader或Single Writer(MRSW)策略进行并发访问。
但是,我不确定这种MRSW政策的粒度。它是在整个数据集中,还是在数据集中的单个命名图形?
编辑:更具体地说,我的要求是我想对不同的命名图形进行只写更新(每个线程写入不同的命名图形)而不进行任何读取操作,是否可能?或者我必须一次更新一个线程。
答案 0 :(得分:2)
鉴于链接文档说
可以直接在数据集上执行操作,而无需使用多读取器或单个写入器(MRSW)策略进行并发访问。
我希望如果您有多个将访问数据集的编写器,即使在不同的命名图中,您也应该使用事务。 TDB Transactions上的文档说明了写事务:
一般模式是:
dataset.begin(ReadWrite.WRITE) ; try { ... dataset.commit() ; } finally { dataset.end() ; }
这些对begin
和end
的调用与数据集关联,而不是与单个命名图关联。
许多三重商店(我认为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不是限制。