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

Reply via email to