David,
Your not executing inside a database level (JDBC) transaction. I'm
afraid model.begin/commit does not know about JDBC properly. You need
to control the JDBC transaction in your code to get isolation between JVMs.
Which SQL database are you using?
Andy
On 10/04/13 16:12, Lebling, David (US SSA) wrote:
The method below is a somewhat over-decorated (with extra non-production checks and error
log messages) version of "write a model to the SDB repository safely" that I am
using. The Individual res (or rather, the in-memory model it is in) is written to the
Model model (obtained via SDBFactory.connectNamedModel), replacing any current contents.
It attempts to protect the model update from horrible concurrency death during the
process. However, I'm seeing that in cases where there are multiple readers and writers
(in different services - i.e., different JVMs) beating on the particular model, the error
messages with "****" appear, sometimes surprisingly often. When the first one
appears, the second one also always appears.
The outcome in the above cases is a repository model that is empty when read
later. The obvious idea is that between model.removeAll() and the later
model.add() the reader is reading the temporarily empty model. I don't know if
that idea is correct, but I don't have any others.
Any suggestions as to what I am doing wrong would be appreciated.
/**
* Single place to write or delete a model from the store
* @param model store-based model
* @param res in-memory resource to write into model, or null to just delete
model
*/
void internalWrite(Model model, Individual res) {
if (model != null) {
try {
logger.debug("begin write model");
model.enterCriticalSection(Lock.WRITE);
model.notifyEvent(GraphEvents.startRead); // TEST I don't know if
this is worth doing
model.begin();
model.removeAll(); // clear out the existing statements in the repo
model
if (res != null) {
Model base = res.getOntModel().getBaseModel();
if (base.size() == 0) {
logger.error("internalWrite: base model empty");
}
model.add(base); // add in-memory model to repository model
if (model.size() == 0) {
logger.error("internalWrite: model empty after add"); // ****
if this happens ****
}
}
else {
logger.debug("internalWrite: resource passed is null: delete");
}
model.commit();
if (model.size() == 0) {
logger.error("internalWrite: model empty after commit"); // ****
this also happens ****
}
}
catch (SDBException ex) {
model.abort();
logger.error(ex);
}
finally {
model.notifyEvent(GraphEvents.finishRead); // TEST I don't know if
this is worth doing
model.leaveCriticalSection();
logger.debug("end write model");
}
}
}
Thanks,
Dave
David Lebling
BAE Systems, Inc.