On 2017-09-13 11:22, Rob Vesse wrote:
> You cannot mix transactional and non-transactional usage together and TDB 
> will explicitly prevent that

But if the transaction is bound to the underlying TDB, and all the
datasets are linked to the same TDB (as in that case), then, why is it
complaining?

> Each dataset instance needs to explicitly begin a transaction

Then, just for (I hope) finally clarifying the behaviour, what would
happen in this case?



     Dataset d = TDBFactory.createDataset(tripleStorePath);
     Dataset d1 = TDBFactory.createDataset(tripleStorePath);
     Dataset d2 = TDBFactory.createDataset(tripleStorePath);

     d1.begin(ReadWrite.READ);

     MultiUnion union = new MultiUnion();
     union.addGraph(d1.getNameModel("whatever1").getGraph());
     union.addGraph(d1.getNameModel("whatever2").getGraph());

     Model m1 = ModelFactory.createModelForGraph(union);

     d1.end();

     d2.begin(ReadWrite.READ);
     union = new MultiUnion();
     union.addGraph(d2.getNameModel("whatever3").getGraph());
     union.addGraph(d2.getNameModel("whatever4").getGraph());

     Model m2 = ModelFactory.createModelForGraph(union);

     d2.end()

     d.begin(ReadWrite.READ);
     Model m3 = ModelFactory.createUnion(m1, m2);
     d.end();

     // Sometime later in the code
     d.begin(ReadWrite.READ);
     // execute SPARQL SELECT over m3
     d.end();


Will the SPARQL SELECT be executed over m3? What is the state (entities
stored) of the m3 model? Is it the same m3 as before or if during the
time before creating and execution of SPARQL the underlying graphs
changed, then m3 has changed as well?





> Rob
> 
> On 13/09/2017 10:01, "George News" <[email protected]> wrote:
> 
>     
>     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,
>     >>> 
>     >> 
>     > 
>     > 
>     > 
>     > 
>     > 
>     > 
>     
> 
> 
> 
> 
> 

Reply via email to