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