When I tried to add a transaction on dest there was an error with a
transaction already  being active.

Does the concurrent modification error indicate that the model was somehow
changed outside of an iterator?  That is where I am used to seeing it.

The iterator call is in a recursive call to extractInfo().

Both graphs are in the same dataset.

all txnX() methods are of the form:

    public static void txnBegin(Graph g) {
        if (g.getTransactionHandler().transactionsSupported()) {
            g.getTransactionHandler().begin();
        }
    }

Stepping through the extract code there is this method:

 public void extractInto( Node root  )
            {
            active.add( root );
            Iterator<Triple> it = extractFrom.find( root, Node.ANY,
Node.ANY );
            while (it.hasNext())
                {
                Triple t = it.next();
                Node subRoot = t.getObject();
                toUpdate.add( t );
                if (! (active.contains( subRoot ) || b.stopAt( t )))
extractInto( subRoot );
                }
            }
        }

When the toUpdate.add(t) is called the
DatasetControlMRSW$IteratorCheckNotConcurrent.eCount
is incremented.

I see in the code comments for IteratorCheckNotConcurrent that it expects
writer to be on a different thread than reader.  Is there a way around that
restriction?  I ask because all other graphs that I have tested work fine
when reading and writing on the same thread.

Thoughts?

Claude




On Fri, Dec 29, 2017 at 10:28 PM, Andy Seaborne <[email protected]> wrote:

> The exception says there is incorrect MRSW use of iterators in the test.
>
> Iterator checking is very old code and I believe it works reliably - it is
> not guaranteed to always catch errors though.  That was never the claim.
>
> Too many details missing to say much else but I don't see any txn on dest.
>
>     Andy
>
>
> On 29/12/17 13:10, Claude Warren wrote:
>
>> fair enough.
>>
>> I created a ContractTest for GraphTxnTDB and discovered a lot of issues
>> with transactions in the contract tests.  I cleaned most of them up but am
>> left with the following:
>>
>>      /**
>>       * This test exposed that the update-existing-graph functionality was
>> broken
>>       * if the target graph already contained any statements with a
>> subject S
>>       * appearing as subject in the source graph - no further Spo
>> statements
>> were
>>       * added.
>>       */
>>      @ContractTest
>>      public void testPartialUpdate() {
>>          Graph source = graphWith(producer.newInstance(), "a R b; b S
>> e");
>>          Graph dest = graphWith(producer.newInstance(), "b R d");
>>          txnBegin(source);
>>          try {
>>              GraphExtract e = new GraphExtract(TripleBoundary.st
>> opNowhere);
>>              e.extractInto(dest, node("a"), source);
>>              txnCommit(source);
>>          }
>>          catch (RuntimeException e)
>>          {
>>              txnRollback(source);
>>              fail( e.getMessage() );
>>
>>          }
>>          txnBegin(source);
>>          assertIsomorphic(
>>                  graphWith( "a R b; b S e; b R d"),
>>                  dest);
>>          txnRollback(source);
>>
>>      }
>>
>>
>> Notes:
>>      graphWith populates the graph with the triples defined in the string
>> using a transaction.
>>      txnRollback performs an abort if transactions are supported.
>>
>> The problem is  that an exception is thrown in the extractInfo() call.
>>
>> java.util.ConcurrentModificationException: Iterator: started at 6, now 7
>>      at
>> org.apache.jena.tdb.sys.DatasetControlMRSW.policyError(Datas
>> etControlMRSW.java:147)
>>      at
>> org.apache.jena.tdb.sys.DatasetControlMRSW.access$000(Datase
>> tControlMRSW.java:32)
>>      at
>> org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotC
>> oncurrent.checkIterConcurrentModification(DatasetControlMRSW.java:103)
>>      at
>> org.apache.jena.tdb.sys.DatasetControlMRSW$IteratorCheckNotC
>> oncurrent.hasNext(DatasetControlMRSW.java:110)
>>      at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265)
>>      at org.apache.jena.atlas.iterator.Iter$2.hasNext(Iter.java:265)
>>      at org.apache.jena.atlas.iterator.Iter.hasNext(Iter.java:886)
>>      at
>> org.apache.jena.util.iterator.WrappedIterator.hasNext(Wrappe
>> dIterator.java:90)
>>      at
>> org.apache.jena.graph.GraphExtract$Extraction.extractInto(
>> GraphExtract.java:80)
>>      at
>> org.apache.jena.graph.GraphExtract$Extraction.extractInto(
>> GraphExtract.java:85)
>>      at org.apache.jena.graph.GraphExtract.extractInto(GraphExtract.
>> java:52)
>>      at
>> org.apache.jena.graph.GraphContractTest.testPartialUpdate(Gr
>> aphContractTest.java:1564)
>>      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>      at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAcce
>> ssorImpl.java:62)
>>      at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMe
>> thodAccessorImpl.java:43)
>>      at java.lang.reflect.Method.invoke(Method.java:498)
>>      at
>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(
>> FrameworkMethod.java:45)
>>      at
>> org.junit.internal.runners.model.ReflectiveCallable.run(Refl
>> ectiveCallable.java:15)
>>      at
>> org.junit.runners.model.FrameworkMethod.invokeExplosively(Fr
>> ameworkMethod.java:42)
>>      at
>> org.junit.internal.runners.statements.InvokeMethod.evaluate(
>> InvokeMethod.java:20)
>>      at
>> org.junit.internal.runners.statements.RunAfters.evaluate(Run
>> Afters.java:30)
>>      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
>>      at
>> org.xenei.junit.contract.ContractTestRunner.runChild(Contrac
>> tTestRunner.java:138)
>>      at
>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit
>> 4ClassRunner.java:47)
>>      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
>>      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
>>      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
>>      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
>>      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
>>      at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
>>      at
>> org.xenei.junit.contract.ContractSuite.runChild(ContractSuite.java:369)
>>      at org.xenei.junit.contract.ContractSuite.runChild(ContractSuit
>> e.java:1)
>>      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
>>      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
>>      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
>>      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
>>      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
>>      at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
>>      at
>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.
>> run(JUnit4TestReference.java:86)
>>      at
>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(
>> TestExecution.java:38)
>>      at
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe
>> sts(RemoteTestRunner.java:459)
>>      at
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTe
>> sts(RemoteTestRunner.java:678)
>>      at
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(
>> RemoteTestRunner.java:382)
>>      at
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(
>> RemoteTestRunner.java:192)
>>
>> Is this a bug, or a known limitation of GraphTxnTDB?
>>
>> Claude
>>
>> On Fri, Dec 29, 2017 at 11:14 AM, Andy Seaborne <[email protected]> wrote:
>>
>> Try it :-)
>>>
>>> Then try running it twice in a JVM.
>>>
>>> And then try TDB2 vs TDB1 vs TIM.
>>>
>>>     Andy
>>>
>>>
>>> On 28/12/17 23:49, Claude Warren wrote:
>>>
>>> Would the following code snippit work
>>>>
>>>>           Graph g = // a TDB graph instance
>>>>           if (g.getTransactionHandler().transactionsSupported()) {
>>>>               Graph initial = graphWith( GraphFactory.createGraphMem(),
>>>>                       "initial hasValue 42; also hasURI hello");
>>>>               Graph extra = graphWith(GraphFactory.createGraphMem(),
>>>>                       "extra hasValue 17; also hasURI world");
>>>>               GraphUtil.addInto(g, initial);
>>>>               g.getTransactionHandler().begin();
>>>>               GraphUtil.addInto(g, extra);
>>>>               g.getTransactionHandler().abort();
>>>>               assertIsomorphic(initial, g);
>>>>
>>>>
>>>> Notes:
>>>>       graphWith populates the graph with the triples defined in the
>>>> string.
>>>>       GraphUtil.addInto() performs no transaction handling and copies
>>>> the
>>>> contents of the second param into the first param.
>>>>
>>>> I suspect that this will/should fail when the begin() is called as the
>>>> transaction as we are switching from not using transactions to using
>>>> them.
>>>>
>>>> Claude
>>>>
>>>>
>>>>
>>
>>


-- 
I like: Like Like - The likeliest place on the web
<http://like-like.xenei.com>
LinkedIn: http://www.linkedin.com/in/claudewarren

Reply via email to