You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@jena.apache.org by Laurent Rucquoy <la...@telemis.com> on 2016/09/14 07:59:55 UTC

ConcurrentModificationException

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(DatasetControlMRSW.java:157)
> at
> org.apache.jena.tdb.sys.DatasetControlMRSW.policyError(DatasetControlMRSW.java:152)
> at
> org.apache.jena.tdb.sys.DatasetControlMRSW.checkConcurrency(DatasetControlMRSW.java:79)
> at
> org.apache.jena.tdb.sys.DatasetControlMRSW.startUpdate(DatasetControlMRSW.java:60)
> at
> org.apache.jena.tdb.store.nodetupletable.NodeTupleTableConcrete.startWrite(NodeTupleTableConcrete.java:65)
> at
> org.apache.jena.tdb.store.nodetupletable.NodeTupleTableConcrete.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

Re: ConcurrentModificationException

Posted by Andy Seaborne <an...@apache.org>.

On 15/09/16 13:16, Laurent Rucquoy wrote:
> Hi Andy,
>
> I've moved the model.close() call inside the transaction (sorry for
> this careless mistake) and it works now !

Maybe, maybe not!

While investigating I couldn't provoke the error either way round - it 
seems to be related to the update performed and I did not manage to 
guess the right kind.  The stack trace does not suggest it is 
model.close related.

What is the SPARQL Update?

	Andy

>
> Thank you very much for your help.
> Laurent
>
>
>
> On 14 September 2016 at 18:28, Andy Seaborne <an...@apache.org> wrote:
>
>> Hi Laurent,
>>
>> On 14/09/16 15:16, Laurent Rucquoy wrote:
>>
>>> 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);
>>>>
>>>
>> What is the update?
>>
>>     if(writeMode) {
>>>>         dataset.commit();
>>>>     }
>>>> } finally {
>>>>
>>>>     model.close();
>>>>
>>>
>> You are using the model after the commit
>>
>>     dataset.end();
>>>> }
>>>>
>>>
>>>
>>         Andy
>>
>>
>>> 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(Datas
>>>> etControlMRSW.java:157)
>>>> at
>>>> org.apache.jena.tdb.sys.DatasetControlMRSW.access$000(Datase
>>>> tControlMRSW.java:32)
>>>> at
>>>> org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotC
>>>> oncurrent.checkCourrentModification(DatasetControlMRSW.java:110)
>>>> at
>>>> org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotC
>>>> oncurrent.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.has
>>>> Next(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.has
>>>> Next(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.has
>>>> Next(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.has
>>>> Next(QueryIteratorBase.java:111)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIterConcat.hasNe
>>>> xtBinding(QueryIterConcat.java:82)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>>> Next(QueryIteratorBase.java:111)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.
>>>> hasNextBinding(QueryIterRepeatApply.java:74)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>>> Next(QueryIteratorBase.java:111)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIterConvert.hasN
>>>> extBinding(QueryIterConvert.java:58)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>>> Next(QueryIteratorBase.java:111)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIterDistinct.get
>>>> InputNextUnseen(QueryIterDistinct.java:104)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIterDistinct.has
>>>> NextBinding(QueryIterDistinct.java:70)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>>> Next(QueryIteratorBase.java:111)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.
>>>> hasNextBinding(QueryIteratorWrapper.java:39)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>>> Next(QueryIteratorBase.java:111)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.
>>>> hasNextBinding(QueryIteratorWrapper.java:39)
>>>> at
>>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>>> Next(QueryIteratorBase.java:111)
>>>> at
>>>> org.apache.jena.sparql.engine.ResultSetStream.hasNext(Result
>>>> SetStream.java:74)
>>>> at
>>>> org.apache.jena.sparql.engine.ResultSetCheckCondition.hasNex
>>>> t(ResultSetCheckCondition.java:59)
>>>>
>>>
>>>
>>>
>>> Regards,
>>> Laurent
>>>
>>>
>>>
>>> On 14 September 2016 at 11:36, Andy Seaborne <an...@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
>>>>>
>>>>>
>>>>>
>>>
>

Re: ConcurrentModificationException

Posted by Laurent Rucquoy <la...@telemis.com>.
Hi Andy,

I've moved the model.close() call inside the transaction (sorry for
this careless mistake) and it works now !

Thank you very much for your help.
Laurent



On 14 September 2016 at 18:28, Andy Seaborne <an...@apache.org> wrote:

> Hi Laurent,
>
> On 14/09/16 15:16, Laurent Rucquoy wrote:
>
>> 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);
>>>
>>
> What is the update?
>
>     if(writeMode) {
>>>         dataset.commit();
>>>     }
>>> } finally {
>>>
>>>     model.close();
>>>
>>
> You are using the model after the commit
>
>     dataset.end();
>>> }
>>>
>>
>>
>         Andy
>
>
>> 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(Datas
>>> etControlMRSW.java:157)
>>> at
>>> org.apache.jena.tdb.sys.DatasetControlMRSW.access$000(Datase
>>> tControlMRSW.java:32)
>>> at
>>> org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotC
>>> oncurrent.checkCourrentModification(DatasetControlMRSW.java:110)
>>> at
>>> org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotC
>>> oncurrent.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.has
>>> Next(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.has
>>> Next(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.has
>>> Next(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.has
>>> Next(QueryIteratorBase.java:111)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIterConcat.hasNe
>>> xtBinding(QueryIterConcat.java:82)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>> Next(QueryIteratorBase.java:111)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIterRepeatApply.
>>> hasNextBinding(QueryIterRepeatApply.java:74)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>> Next(QueryIteratorBase.java:111)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIterConvert.hasN
>>> extBinding(QueryIterConvert.java:58)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>> Next(QueryIteratorBase.java:111)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIterDistinct.get
>>> InputNextUnseen(QueryIterDistinct.java:104)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIterDistinct.has
>>> NextBinding(QueryIterDistinct.java:70)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>> Next(QueryIteratorBase.java:111)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.
>>> hasNextBinding(QueryIteratorWrapper.java:39)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>> Next(QueryIteratorBase.java:111)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorWrapper.
>>> hasNextBinding(QueryIteratorWrapper.java:39)
>>> at
>>> org.apache.jena.sparql.engine.iterator.QueryIteratorBase.has
>>> Next(QueryIteratorBase.java:111)
>>> at
>>> org.apache.jena.sparql.engine.ResultSetStream.hasNext(Result
>>> SetStream.java:74)
>>> at
>>> org.apache.jena.sparql.engine.ResultSetCheckCondition.hasNex
>>> t(ResultSetCheckCondition.java:59)
>>>
>>
>>
>>
>> Regards,
>> Laurent
>>
>>
>>
>> On 14 September 2016 at 11:36, Andy Seaborne <an...@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
>>>>
>>>>
>>>>
>>

Re: ConcurrentModificationException

Posted by Andy Seaborne <an...@apache.org>.
Hi Laurent,

On 14/09/16 15:16, Laurent Rucquoy wrote:
> 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);

What is the update?

>>     if(writeMode) {
>>         dataset.commit();
>>     }
>> } finally {
>>
>>     model.close();

You are using the model after the commit

>>     dataset.end();
>> }
>

	Andy

>
> 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 <an...@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
>>>
>>>
>

Re: ConcurrentModificationException

Posted by Laurent Rucquoy <la...@telemis.com>.
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 <an...@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
>>
>>

Re: ConcurrentModificationException

Posted by Andy Seaborne <an...@apache.org>.
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(DatasetControlMRSW.java:157)
>> at
>> org.apache.jena.tdb.sys.DatasetControlMRSW.policyError(DatasetControlMRSW.java:152)
>> at
>> org.apache.jena.tdb.sys.DatasetControlMRSW.checkConcurrency(DatasetControlMRSW.java:79)
>> at
>> org.apache.jena.tdb.sys.DatasetControlMRSW.startUpdate(DatasetControlMRSW.java:60)
>> at
>> org.apache.jena.tdb.store.nodetupletable.NodeTupleTableConcrete.startWrite(NodeTupleTableConcrete.java:65)
>> at
>> org.apache.jena.tdb.store.nodetupletable.NodeTupleTableConcrete.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
>