Hi Andy, Thank you for your help.
I have tested the following code according to your suggestions (get the model inside the transaction and remove the use of locks): dataset.begin(ReadWrite.WRITE); > Model model = dataset.getNamedModel("http://my-model-name"); > try { > UpdateAction.parseExecute(sparql, model); > if(writeMode) { > dataset.commit(); > } > } finally { > > model.close(); > dataset.end(); > } When multiple updates are made on our TDB-backed dataset, the java.util. ConcurrentModificationException is still thrown, leaving the dataset in an inaccessible state. Here is the stacktrace part: Caused by: java.util.ConcurrentModificationException: Iterator: started at > 5, now 8 > at > org.apache.jena.tdb.sys.DatasetControlMRSW.policyError(DatasetControlMRSW.java:157) > at > org.apache.jena.tdb.sys.DatasetControlMRSW.access$000(DatasetControlMRSW.java:32) > at > org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotConcurrent.checkCourrentModification(DatasetControlMRSW.java:110) > at > org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotConcurrent.hasNext(DatasetControlMRSW.java:118) > at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265) > at org.apache.jena.atlas.iterator.Iter.hasNext(Iter.java:870) > at org.apache.jena.atlas.iterator.Iter$1.hasNext(Iter.java:192) > at org.apache.jena.atlas.iterator.Iter.hasNext(Iter.java:870) > at > org.apache.jena.atlas.iterator.RepeatApplyIterator.hasNext(RepeatApplyIterator.java:58) > at > org.apache.jena.tdb.solver.SolverLib$IterAbortable.hasNext(SolverLib.java:195) > at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265) > at > org.apache.jena.sparql.engine.iterator.QueryIterPlainWrapper.hasNextBinding(QueryIterPlainWrapper.java:53) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.makeNextStage(QueryIterRepeatApply.java:101) > at > org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:65) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265) > at > org.apache.jena.atlas.iterator.RepeatApplyIterator.hasNext(RepeatApplyIterator.java:45) > at > org.apache.jena.tdb.solver.SolverLib$IterAbortable.hasNext(SolverLib.java:195) > at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265) > at > org.apache.jena.sparql.engine.iterator.QueryIterPlainWrapper.hasNextBinding(QueryIterPlainWrapper.java:53) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265) > at > org.apache.jena.atlas.iterator.RepeatApplyIterator.hasNext(RepeatApplyIterator.java:45) > at > org.apache.jena.tdb.solver.SolverLib$IterAbortable.hasNext(SolverLib.java:195) > at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265) > at > org.apache.jena.sparql.engine.iterator.QueryIterPlainWrapper.hasNextBinding(QueryIterPlainWrapper.java:53) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.iterator.QueryIterConcat.hasNextBinding(QueryIterConcat.java:82) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.hasNextBinding(QueryIterRepeatApply.java:74) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.iterator.QueryIterConvert.hasNextBinding(QueryIterConvert.java:58) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.iterator.QueryIterDistinct.getInputNextUnseen(QueryIterDistinct.java:104) > at > org.apache.jena.sparql.engine.iterator.QueryIterDistinct.hasNextBinding(QueryIterDistinct.java:70) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.hasNextBinding(QueryIteratorWrapper.java:39) > at > org.apache.jena.sparql.engine.iterator.QueryIteratorBase.hasNext(QueryIteratorBase.java:111) > at > org.apache.jena.sparql.engine.ResultSetStream.hasNext(ResultSetStream.java:74) > at > org.apache.jena.sparql.engine.ResultSetCheckCondition.hasNext(ResultSetCheckCondition.java:59) Regards, Laurent On 14 September 2016 at 11:36, Andy Seaborne <a...@apache.org> wrote: > Hi Laurant, > > Try getting the model inside transaction, not passing it across > transaction boundaries. > > dataset.begin(ReadWrite.WRITE); > try { > Model model = dataset.get... > ... > dataset.commit() ; > } ... > > In 3.1.0, the model is (sort of) connected to the transaction in which it > is created. This is fixed in the next release but style-wise, because > model are just views of the database, they are related to transactions. > > No need to close the model but it's harmless to do so. > > You don't need the locking as well as transactions. > > Andy > > > > On 14/09/16 08:59, Laurent Rucquoy wrote: > >> Hello, >> >> We use a Jena TDB-backed dataset (release 3.1.0) accessed through a single >> JVM multi-threaded application running generally on a Microsoft Windows >> server. >> >> The read and write accesses are made using transaction and read/write >> locks. >> Here is the SPARQL update code we use: >> >> dataset.begin(ReadWrite.WRITE); >> >>> model.enterCriticalSection(Lock.WRITE); >>> try { >>> UpdateAction.parseExecute(sparql, model); >>> if(writeMode) { >>> dataset.commit(); >>> } >>> } finally { >>> model.leaveCriticalSection(); >>> model.close(); >>> dataset.end(); >>> } >>> >> >> >> Note that our SPARQL query code implements also read transactions and >> locks. >> >> When multiple updates are made on our TDB-backed dataset, a >> java.util.ConcurrentModificationException is sometimes thrown, leaving >> the >> dataset in an inaccessible state. >> Here is the stacktrace part: >> >> >> ... >>> Caused by: java.util.ConcurrentModificationException: Reader = 1, >>> Writer = >>> 1 >>> at >>> org.apache.jena.tdb.sys.DatasetControlMRSW.policyError(Datas >>> etControlMRSW.java:157) >>> at >>> org.apache.jena.tdb.sys.DatasetControlMRSW.policyError(Datas >>> etControlMRSW.java:152) >>> at >>> org.apache.jena.tdb.sys.DatasetControlMRSW.checkConcurrency( >>> DatasetControlMRSW.java:79) >>> at >>> org.apache.jena.tdb.sys.DatasetControlMRSW.startUpdate(Datas >>> etControlMRSW.java:60) >>> at >>> org.apache.jena.tdb.store.nodetupletable.NodeTupleTableConcr >>> ete.startWrite(NodeTupleTableConcrete.java:65) >>> at >>> org.apache.jena.tdb.store.nodetupletable.NodeTupleTableConcr >>> ete.sync(NodeTupleTableConcrete.java:249) >>> >> >> >> How can we avoid such a situation ? >> Can we safely do without read/write locks when we use transactions in a >> single JVM multi-threaded application ? >> >> Thank you in advance for your help. >> >> Sincerely, >> Laurent >> >>