Queries cannot be run directly on a session with an open transaction; either run from within the transaction or use a different session

Viewed 2028

I am new using Neo4J and I came across this error today, in my conception, I am closing and opening the sessions, however I am receiving this error.

I simply want to know if there is already a node with the email received in the request, if yes, do not register, if not, then do the registration normally.

does anyone have any idea where I'm going wrong, again I'm a layman in neo4j

thanks in advance

exports.createUser = (req, res) => {

const userName = req.body.name;
const userEmail = req.body.email;
const userPassword = req.body.password;

const alreadyRegistered = 
    session.run(
        `MATCH (n { email: '${userEmail}' })
        RETURN n`
    );
alreadyRegistered.then(result => {
    session.close();
    if(result.records.length){
        res.send('Já existi um usuário com este e-mail cadastrado');
    }
});

const create =
    session.run(
        `CREATE (n:User {name: '${userName}', email: '${userEmail}', password: '${userPassword}'})
        RETURN n`
    );

    create.then(result => {
    session.close();
  
    const singleRecord = result.records[0];
    const node = singleRecord.get(0);
  
    res.send(`Usuário ${userName} cadastrado com sucesso`)

    driver.close();
});
};
1 Answers

Sessions are light weight objects designed for a single query to run at a time.

I am guessing you are calling createUser right after the alreadyRegistered check. Since these are async calls, you are inadvertently executing two queries at the same time in the same session.

To fix this, you want to create a new session for every new query run in the database if you can't guarantee / don't want serial execution of queries:

const session = this.driver.session();
const results = session.run(/*...*/);

results.then(async results => {
            session.close();
            /*...*/
    })

This is explained in the api here: https://github.com/neo4j/neo4j-javascript-driver/commit/a6ed396a31c4c2e6420218792172fc5535b8e4e1

Related issue: https://github.com/neo4j/neo4j-javascript-driver/issues/306#issuecomment-366931341

Also, make sure you are waiting for the alreadyRegistered query to finish before making a query to createUser. Its easier to use async / await than chaining .then everywhere:

const result = await alreadyRegistered();
if(result.records.length){
    res.send('Já existi um usuário com este e-mail cadastrado');
}

const user = await createUser();
Related