There is a single service (and JVM) that writes the models (at least in this 
case), and many that read them. There is a single Store (and hence 
SDBConnection) for the service.

I originally wrote the code so that it used the 
model.enterCriticalSection/model.leaveCriticalSection methods. This did not 
seem to prevent other threads from writing the same model inside the critical 
section.

My belief is that model.begin/model.commit aren't permitted to nest, so it's 
key to avoid one thread trying to do a transaction when another already is.

So, I tried doing both: model.enterCriticalSection + model.begin, finishing 
with model.commit + model.leaveCriticalSection. That doesn't seem to do the 
trick either. I'm still getting "already in transaction," meaning other threads 
are trying to write the same model and not being blocked by the critical 
section.

So, is the ModelLock not a thread-safe lock?

Dave

-----Original Message-----
From: Joshua TAYLOR [mailto:[email protected]] 
Sent: Friday, September 07, 2012 1:09 PM
To: [email protected]
Subject: Re: Model critical sections

On Fri, Sep 7, 2012 at 12:17 PM, Lebling, David (US SSA) 
<[email protected]> wrote:
> 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().

(Having discussed this with a coworker...) Are you getting these issues within 
a single JVM with multiple threads that all use the same JDBC connection?  If 
this is the case, then this thread from 2010 [1] is relevant, which states, "If 
you need transactions between the concurrent operations, you will either need 
to use multiple JDBC connections, or use a single connection and use in-JVM 
locking (e.g.
MRSW locks)."

> 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".

For the reading, I don't think the transactions are necessary;  each read will 
be from whatever the last state of the database is.  Without transactions on 
the writes, you could end up reading from a model when only part of a write has 
happened.  With transactions on the writes, you'll only be reading from models 
where writes have been completed.
You could, of course, still be reading from a blank model if your read executes 
before any of your write transactions have been committed.

//JT

[1] http://tech.groups.yahoo.com/group/jena-dev/message/43942

--
Joshua Taylor, http://www.cs.rpi.edu/~tayloj/

Reply via email to