majensen / perlbolt

Neo4j server agent using Bolt protocol
Apache License 2.0
4 stars 2 forks source link

Neo4j::Bolt::Txn becomes autocommit transaction after server-side error #52

Open johannessen opened 1 year ago

johannessen commented 1 year ago

After a Neo4j server error occurs on a query run inside an explicit transaction, that transaction object behaves as if aliased to the connection object. In other words, any further queries run on the same transaction object are executed on the server as if this was an autocommit transaction.

In the following code snippet, the CREATE should never be committed successfully because the transaction is already failed due to the earlier syntax error.

my $id = 'd270c798-ef8c-42de-8215-02351ce82c16';

{
  my $cxn = Neo4j::Bolt->connect(...);
  $cxn->run_query("MATCH (a {test: \$id }) DELETE a", {id => $id});

  my $txn = Neo4j::Bolt::Txn->new($cxn);
  $txn->run_query("syntax error!");
  $txn->run_query("CREATE (a {test: \$id })", {id => $id});  # successful commit
  $txn->rollback;
}

{
  my $cxn = Neo4j::Bolt->connect(...);
  my @query = ( "MATCH (a {test: \$id }) RETURN a", {id => $id} );
  my $node  = ( $cxn->run_query(@query)->fetch_next )[0];

  say $node ? "Found node: $node->{properties}->{test}" : "Node not found";
     # Found node: d270c798-ef8c-42de-8215-02351ce82c16
}

For what it’s worth, I only noticed this while hunting down an unrelated bug in Neo4j::Driver. This issue is never triggered by the driver because it tracks transaction state. The CREATE and also the explicit rollback both would die in Neo4j::Driver with a “transaction already closed” message. Consequently, strictly from the perspective of the driver, I don’t need a code fix here. It’d be adequate if this issue was simply added to the Neo4j::Bolt::Txn documentation as a known limitation.