You cannot mix transactional and non-transactional usage together and TDB will 
explicitly prevent that

Each dataset instance needs to explicitly begin a transaction

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