[ 
https://issues.apache.org/jira/browse/TINKERPOP-3142?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Ken Hu updated TINKERPOP-3142:
------------------------------
    Description: 
Originally discovered from:

https://stackoverflow.com/questions/79467860/issue-with-transactions-in-local-tinkerpop-gremlin-setup
[https://groups.google.com/g/gremlin-users/c/NRwb4xy2eXs]

 

TinkerTransactionGraph might leave a "isDeleted" TinkerElementContainer hanging 
around if a read occurs during the commit of a drop(). This leads to later 
errors when trying to add that element back as it "isDeleted" leading to an 
exception.

The following test can sometimes reproduce the error (it's a multithreading 
issue so it doesn't always reproduce).

 
{code:java}
@Test
public void shouldAddThenDeleteThenAddBackInSeparateTransactions() throws 
InterruptedException {
    final TinkerTransactionGraph graph = TinkerTransactionGraph.open();
    final GraphTraversalSource g = graph.traversal();
    final GraphTraversalSource gtx = g.tx().begin();

    CountDownLatch signal = new CountDownLatch(1);

    gtx.addV().property(T.id, 1).next();
    gtx.tx().commit();

    Thread reader = new Thread(() -> {
        while (signal.getCount() > 0) {
            g.V().id().toList();
            g.tx().commit();
        }
    });
    reader.start();

    Thread.sleep(50);

    g.V(1).drop().iterate();
    g.tx().commit();

    Thread.sleep(50);

    g.addV().property(T.id, 1).next();
    g.tx().commit();

    signal.countDown();
    reader.join();

    assertEquals(1, graph.getVertices().size());
} {code}
Should a read occur when trying to delete the vertex, the usesInTransactions is 
incremented 
([https://github.com/apache/tinkerpop/blob/3.7.3/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerElementContainer.java#L100])
 so that it won't be deleted during the commit as its uses isn't 0 
([https://github.com/apache/tinkerpop/blob/3.7.3/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerElementContainer.java#L232).]

 

This behavior of incrementing the use count with reads gives more consistent 
reads, however, the tradeoff is that it can cause TransactionExceptions to 
occur. So, it would be best if this could be resolved while keeping the read 
behavior consistent.

 

  was:
TinkerTransactionGraph might leave a "isDeleted" TinkerElementContainer hanging 
around if a read occurs during the commit of a drop(). This leads to later 
errors when trying to add that element back as it "isDeleted" leading to an 
exception.

The following test can sometimes reproduce the error (it's a multithreading 
issue so it doesn't always reproduce).

 
{code:java}
@Test
public void shouldAddThenDeleteThenAddBackInSeparateTransactions() throws 
InterruptedException {
    final TinkerTransactionGraph graph = TinkerTransactionGraph.open();
    final GraphTraversalSource g = graph.traversal();
    final GraphTraversalSource gtx = g.tx().begin();

    CountDownLatch signal = new CountDownLatch(1);

    gtx.addV().property(T.id, 1).next();
    gtx.tx().commit();

    Thread reader = new Thread(() -> {
        while (signal.getCount() > 0) {
            g.V().id().toList();
            g.tx().commit();
        }
    });
    reader.start();

    Thread.sleep(50);

    g.V(1).drop().iterate();
    g.tx().commit();

    Thread.sleep(50);

    g.addV().property(T.id, 1).next();
    g.tx().commit();

    signal.countDown();
    reader.join();

    assertEquals(1, graph.getVertices().size());
} {code}
Should a read occur when trying to delete the vertex, the usesInTransactions is 
incremented 
(https://github.com/apache/tinkerpop/blob/3.7.3/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerElementContainer.java#L100)
 so that it won't be deleted during the commit as its uses isn't 0 
([https://github.com/apache/tinkerpop/blob/3.7.3/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerElementContainer.java#L232).]

 

This behavior of incrementing the use count with reads gives more consistent 
reads, however, the tradeoff is that it can cause TransactionExceptions to 
occur. So, it would be best if this could be resolved while keeping the read 
behavior consistent.

 


> TinkerTransactionGraph doesn't remove deleted elements in threaded scenario
> ---------------------------------------------------------------------------
>
>                 Key: TINKERPOP-3142
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-3142
>             Project: TinkerPop
>          Issue Type: Bug
>          Components: tinkergraph
>    Affects Versions: 3.7.3
>            Reporter: Ken Hu
>            Priority: Major
>
> Originally discovered from:
> https://stackoverflow.com/questions/79467860/issue-with-transactions-in-local-tinkerpop-gremlin-setup
> [https://groups.google.com/g/gremlin-users/c/NRwb4xy2eXs]
>  
> TinkerTransactionGraph might leave a "isDeleted" TinkerElementContainer 
> hanging around if a read occurs during the commit of a drop(). This leads to 
> later errors when trying to add that element back as it "isDeleted" leading 
> to an exception.
> The following test can sometimes reproduce the error (it's a multithreading 
> issue so it doesn't always reproduce).
>  
> {code:java}
> @Test
> public void shouldAddThenDeleteThenAddBackInSeparateTransactions() throws 
> InterruptedException {
>     final TinkerTransactionGraph graph = TinkerTransactionGraph.open();
>     final GraphTraversalSource g = graph.traversal();
>     final GraphTraversalSource gtx = g.tx().begin();
>     CountDownLatch signal = new CountDownLatch(1);
>     gtx.addV().property(T.id, 1).next();
>     gtx.tx().commit();
>     Thread reader = new Thread(() -> {
>         while (signal.getCount() > 0) {
>             g.V().id().toList();
>             g.tx().commit();
>         }
>     });
>     reader.start();
>     Thread.sleep(50);
>     g.V(1).drop().iterate();
>     g.tx().commit();
>     Thread.sleep(50);
>     g.addV().property(T.id, 1).next();
>     g.tx().commit();
>     signal.countDown();
>     reader.join();
>     assertEquals(1, graph.getVertices().size());
> } {code}
> Should a read occur when trying to delete the vertex, the usesInTransactions 
> is incremented 
> ([https://github.com/apache/tinkerpop/blob/3.7.3/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerElementContainer.java#L100])
>  so that it won't be deleted during the commit as its uses isn't 0 
> ([https://github.com/apache/tinkerpop/blob/3.7.3/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerElementContainer.java#L232).]
>  
> This behavior of incrementing the use count with reads gives more consistent 
> reads, however, the tradeoff is that it can cause TransactionExceptions to 
> occur. So, it would be best if this could be resolved while keeping the read 
> behavior consistent.
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to