Joshua, Thanks for the suggestion. I added a TransactionHandlerSDB to my code that writes to the repository, and appropriate begin()/commit() pairs.
I have multiple clients calling the code fairly often (this is a stress test case, by the way), and what happens is that one client's input starts a write transaction (begin()) on a graph and before it finishes (commit()) another client's input starts another write transaction on the same graph. An exception "Already in a transaction" is thrown. Does that mean that begin() doesn't block if a transaction is in progress? (The code just seems to check a flag before throwing the exception.) Does the user of a TransactionHandler have to perform his own blocking? There doesn't seem to be a way to check if a transaction is in progress before calling begin(). When I use this mechanism to do read transactions (i.e., to mimic the critical section behavior I had before), the commit() method says "WARN: nothing to commit". My top-level goal here is to be able to have multiple clients read and write named graphs in the SDB database without interference from other clients, just in case that's not clear. Dave Lebling -----Original Message----- From: Joshua TAYLOR [mailto:[email protected]] Sent: Friday, September 07, 2012 10:41 AM To: [email protected] Subject: Re: Model critical sections On Fri, Sep 7, 2012 at 10:34 AM, Joshua TAYLOR <[email protected]> wrote: > On Fri, Sep 7, 2012 at 9:08 AM, Lebling, David (US SSA) > <[email protected]> wrote: >> I have a suite of webservices which use OWL ontologies stored as named >> graphs in an SDB database. I also have a set of Java objects that provide a >> POJO façade over ontology class instances. These instances import many or >> even all of the OWL ontologies, so I have an OntDocumentManager which points >> to cached versions of the ontologies. >> >> When an ontology changes, I need to update it in the database, then re-cache >> it in the OntDocumentManager. During those operations (update ontology graph >> in database, update cached version in OntDocumentManager) I am within a >> try/finally block that (respectively) is a write lock or a read lock. >> >> So a sketch (not the full implementation) of the code for writing and >> reading would be: >> >> void update(String name, Model newModel) { Model model = >> SDBFactory.connectNamedModel(store, name); try { >> model.enterCriticalSection(false); // write >> model.removeAll(); >> model.add(newModel); >> } >> finally { >> model.leaveCriticalSection(); } } >> >> void cache(OntDocumentManager mgr, String name) { >> Model model = SDBFactory.connectNamedModel(store, name); >> Model cachedModel = createModel(); // this method creates an >> OWL_MEM model with the doc mgr as its document manager, etc. >> try { >> model.enterCriticalSection(true); // read >> cachedModel.add(model); >> } >> finally { >> model.leaveCriticalSection(); } >> mgr.addModel(name, cachedModel, true); } >> >> What appears to happen is that these critical sections don't appear to >> inhibit other users (in my tests I have five) of the SDB database from >> modifying the stored graph. Readers of the graphs sometimes end up with >> empty graphs. I will sometimes end up with stored graphs that are empty, or >> inconsistent in some way that eventually corrupts the underlying tables in >> the database, requiring a complete reinitialization. I also get >> IllegalThreadState exceptions. Many different exceptions are thrown, with >> little obvious consistency. >> >> Is critical section only good within a JVM? Do I need to use some sort of >> transaction instead? > > The "Concurrent access to models" document [1] describes the Lock > mechanisms that you're using now, but says that they're for the > "multiple threads in a single JVM" and to use transactions for > database backed models. I haven't used SDB (or TDB), so I can't point > you to the documentation on those systems, but I think those are what > you need; hopefully someone else will chime in. After a bit more Googling, I think you might be interested in the javadoc pages for TransactionHandler [1] and TransactionHandlerSDB [2], and Graph#getTransactionHandler() [3]. Hope this helps, //JT [1] http://jena.apache.org/documentation/javadoc/jena/com/hp/hpl/jena/graph/TransactionHandler.html [2] http://jena.apache.org/documentation/javadoc/sdb/com/hp/hpl/jena/sdb/graph/TransactionHandlerSDB.html [3] http://jena.apache.org/documentation/javadoc/jena/com/hp/hpl/jena/graph/Graph.html#getTransactionHandler() -- Joshua Taylor, http://www.cs.rpi.edu/~tayloj/
