On 2017-09-12 12:05, Rob Vesse wrote:
> I think that Andy’s response was perhaps not comprehensive enough.
>
> As he explained a storage area supports any number of read
> transactions and at the most one write transaction. The number of
> active transactions is centrally managed within the JVM and scoped by
> the storage area.
>
> However, each dataset instance you create has its own isolated
> transactional view onto this storage. This allows for transactions to
> interleave safely, that point at which the transaction begins will
> dictate what view each dataset instance gets.
I have being doing some test with different dataset instances and the expected
behaviour from your answer (at least what I understood) is not working.
Dataset d = TDBFactory.createDataset(tripleStorePath);
Dataset d1 = TDBFactory.createDataset(tripleStorePath);
Dataset d2 = TDBFactory.createDataset(tripleStorePath);
d.begin(ReadWrite.READ);
MultiUnion union = new MultiUnion();
union.addGraph(d1.getNameModel("whatever1").getGraph());
union.addGraph(d1.getNameModel("whatever2").getGraph());
Model m1 = ModelFactory.createModelForGraph(union);
union = new MultiUnion();
union.addGraph(d2.getNameModel("whatever3").getGraph());
union.addGraph(d2.getNameModel("whatever4").getGraph());
Model m2 = ModelFactory.createModelForGraph(union);
Model m3 = ModelFactory.createUnion(m1, m2);
d.end();
In my case I get an exception not in transaction when creating m3. Is this the
expected? From my understanding of your explanation there shouldn't be any
problem.
org.apache.jena.tdb.transaction.TDBTransactionException: Not in a transaction
at
org.apache.jena.tdb.transaction.DatasetGraphTransaction.get(DatasetGraphTransaction.java:117)
~[jena-tdb-3.2.0.jar:3.2.0]
at
org.apache.jena.tdb.transaction.DatasetGraphTransaction.getDatasetGraphToQuery(DatasetGraphTransaction.java:80)
~[jena-tdb-3.2.0.jar:3.2.0]
at
org.apache.jena.tdb.store.GraphTxnTDB.getDatasetGraphTDB(GraphTxnTDB.java:49)
~[jena-tdb-3.2.0.jar:3.2.0]
at
org.apache.jena.tdb.store.GraphTDB.createPrefixMapping(GraphTDB.java:80)
~[jena-tdb-3.2.0.jar:3.2.0]
at
org.apache.jena.graph.impl.GraphBase.getPrefixMapping(GraphBase.java:165)
~[jena-core-3.2.0.jar:3.2.0]
at org.apache.jena.graph.compose.Dyadic.<init>(Dyadic.java:44)
~[jena-core-3.2.0.jar:3.2.0]
at org.apache.jena.graph.compose.Union.<init>(Union.java:37)
~[jena-core-3.2.0.jar:3.2.0]
at
org.apache.jena.rdf.model.ModelFactory.createUnion(ModelFactory.java:309)
~[jena-core-3.2.0.jar:3.2.0]
.........
Any idea? Sorry for insisting that much in the issue :(
> So for example you
> could start a read transaction that is long-running, have a short
> write transaction and then another read transaction. The first read
> transaction is seeing the state of the database prior to the write
> whereas the second read transaction would be seeing the state of the
> database after the write.
>
> Rob
>
> On 12/09/2017 10:24, "George News" <[email protected]> wrote:
>
> On 2017-09-12 10:43, Andy Seaborne wrote:
>> They are per storage area.
>>
>> This blocks and never prints "DONE"
>>
>> Location loc = Location.create("DB"); Dataset dataset1 =
>> TDBFactory.createDataset(loc); Dataset dataset2 =
>> TDBFactory.createDataset(loc); dataset1.begin(ReadWrite.WRITE) ;
>> dataset2.begin(ReadWrite.WRITE) ; System.out.println("DONE");
>>
>> but if either a READ, it will work - there and be many readers and
>> one writer at a time. The readers will not see the updated by the
>> writer even after the writer commits.
>
> I understands that but I still think they are not liked to the
> storage area. If you put
>
> Location loc = Location.create("DB"); Dataset dataset1 =
> TDBFactory.createDataset(loc); Dataset dataset2 =
> TDBFactory.createDataset(loc); dataset1.begin(ReadWrite.READ) ;
> System.out.println(dataset1.isInTransaction());
> System.out.println(dataset2.isInTransaction());
> dataset2.begin(ReadWrite.READ) ; System.out.println("DONE");
>
> It will print true for dataset1 and false for dataset2 cases. This
> means that the transaction is linked to the object Dataset and not
> the real location. Or at least this is what is happening to me.
>
> Therefore I think this is a bug :( as the transaction READ is opened
> over the same location. I haven't checked for the WRITE but I guess
> it should be the same. If you write on a dataset and you have a
> several transactions opened this means you will have a kind of a
> counter (semaphore) and when you call the .end() you finish them.
>
>>
>> Creating the datasets is quite cheap. It is not really creating
>> everything everytime. But a statics works as well; Fuseki uses a
>> static registry of datasets.
>>
>> (it's called "connect", "not "create" in TDB2 to make that
>> clearer).
>>
>> Andy
>
> I think the static will be the way to go for me for the cleanness of
> the code, as otherwise it will more complex to handle.
>
>>
>> On 11/09/17 15:57, George News wrote:
>>> Hi all,
>>>
>>> I'm facing an issue that I guess it was implemented that way for
>>> some reason. The issue is that I thought that transactions were
>>> Dataset based, not the object but the TDB or whatever database
>>> you use.
>>>
>>> However while developing my service I have noticed that if you
>>> open 2 datasets on the same TDB
>>>
>>> Dataset dataset1 = TDBFactory.createDataset(tripleStorePath);
>>> Dataset dataset2 = TDBFactory.createDataset(tripleStorePath);
>>>
>>> then each dataset has it's own transaction pointer, that is,
>>> read/write operations are block per object. Is that the expected
>>> behaviour? Why is like this and not blocked per triple store?
>>>
>>> Therefore my question now goes in the direction of which is
>>> better. I'm developing a webservice that is working against the
>>> same triple store path. The Dataset object I create on each call
>>> is link to the instance of the class (not static). Then, how
>>> should I proceed? Should I create the Dataset variable as static,
>>> so this way I only have one object for all?
>>>
>>> Thanks Regards,
>>>
>>
>
>
>
>
>
>