Execute code sequentially in write transaction

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?

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.

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