Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
10-18-2019 07:27 AM
Hi there,
This may be my knowledge of JavaScript, but I can't figure out how to run two statements sequentially within the transaction functions API.
this.session.writeTransaction(tx => {
tx.run("CREATE (p:Person {id: 1})").then(r => {
tx.run("MATCH (p:Person {id: 1}) RETURN p").then(r => {
console.log("success");
}).catch(e => {
console.log("inner catch", e);
});
});
});
AFAIK, this should work, but instead I get the error from the inner catch, Cannot run statement, because transaction has already been successfully closed
. What's the problem?
10-21-2019 02:14 AM
I think that this was just a thinko, the version that works seems to be:
const txResult = this.session!.writeTransaction(tx => {
const p1 = tx.run("CREATE (p:Person {id: 1})");
const p2 = tx.run("MATCH (p:Person {id: 1}) RETURN p");
return [p1, p2];
});
Which is actually more straightforward-looking, but it wasn't clear to me that the driver serializes the actual application of .run
calls within the transaction. When looking at that code it looks like there's a possible race condition there because MATCH may execute before CREATE has completed. However in practice it seems that there is no such race condition. I'm not sure if that's a property of the JS event loop itself, or something that is explicitly enforced by the driver (or the backend) using locks.
12-03-2019 06:10 AM
I know it will error if you have a running transaction and you try another tx.run, could be that p1 is always winning the race. You could do:
const txResult = this.session!.writeTransaction(async tx => {
await tx.run("CREATE (p:Person {id: 1})");
return tx.run("MATCH (p:Person {id: 1}) RETURN p");
});
Your original one would have worked (I think) if you had a return in there so the session knew to wait (not 100% sure on this....)
this.session.writeTransaction(tx => {
return tx.run("CREATE (p:Person {id: 1})").then(r => {
return tx.run("MATCH (p:Person {id: 1}) RETURN p").then(r => {
console.log("success");
}).catch(e => {
console.log("inner catch", e);
});
});
});
And lastly (I know you've already solved it... but always fun to have options!) in this case you could just do it all in one query:
CREATE (p:Person {id: 1}) RETURN p
All the sessions of the conference are now available online