简体   繁体   中英

Sequelize.js Transaction problem with postgreSQL

I have a problem with transactions.

This is my case :

  • I use node.js as my backend with sequelize.js
  • I use angular as my frontend
  • I use PostgreSQL as my Database
  • I have to run an update, then a insert (in one service), and finally query the result (in another service).

So, In the first service, I make an UPDATE and then a INSERT and I use transaction to rollback if there's an error in the process. My code is like:

models.sequelize.transaction(t => {
    return models.table_name.update({ ... },{ where:{ ... },transaction: t })
    .then(()=>{
        return models.sequelize.query(" ... ",{ transaction:t })
        .then(result=>{
             res.status(200).send(result);
             // Everything OK and finished?
        }).catch(err=>{
              t.rollback;
              res.status(500).send(err);
        });
    }).catch(err=>{
         t.rollback;
         res.status(500).send(err);
    });
});

In angular I call the service for the "update and insert" (above), and after it is finished I call another service that queries the table I am updating and inserting.

There is the problem . I've noticed that the commit is done after I query my second service, the first service returns that it is finished but it is not.

For example, I have the next set of data:

A    true
B    true
C    true

I run the "update and insert" (from angular) to get:

A    false
B    false
C    false
D    false

When I get the result of that service I immediately run (from angular), another service that queries that table. But instead of getting the false rows I get the true rows and without the insert:

A    true
B    true
C    true

Like nothing would have happened.

The funny thing is that if I remove the transaction from the code, and just do the update and insert without begin and commit (in sequelize), It works. And I get the updated rows:

A    false
B    false
C    false
D    false

For obvious reasons, this happens very fast. Using the transaction, if I set an interruption point and let the "update and insert" finish, the query service shows me what I need. If I remove the transaction, I get the result that I want, but if anything happens I miss the rollback....

Any clue of what's going on and how to fix it?

NOTE: I've tried to add t.commit but the result is the same.

models.sequelize.transaction(t => {
    return models.table_name.update({ ... },{ where:{ ... },transaction: t })
    .then(()=>{
        return models.sequelize.query(" ... ",{ transaction:t })
        .then(result=>{
             t.commit;// <--- COMMIT
             res.status(200).send(result);
             // Everything OK and finished?
        }).catch(err=>{
              t.rollback;
              res.status(500).send(err);
        });
    }).catch(err=>{
         t.rollback;
         res.status(500).send(err);
    });
});

@florin from sequelize slack answered me, so I put his answer here:

http://docs.sequelizejs.com/manual/tutorial/transactions.html

  1. the transaction commits only after the promise chain you're returning is done. this means that you should move the .then line at the end, because sequelize.transaction also returns a promise and that is when the transaction is finished
  2. you may want to call t.rollback() instead of just referencing it as t.rollback without the parentheses

So, the answer was that I have to put the result in the transaction .then like:

models.sequelize.transaction(t => {
    return models.table_name.update({ ... },{ where:{ ... },transaction: t })
    .then(()=>{
        return models.sequelize.query(" ... ",{ transaction:t })
        .catch(err=>{
              t.rollback();
              res.status(500).send(err);
        });
    }).catch(err=>{
         t.rollback();
         res.status(500).send(err);
    });
}).then(result=>{ // <-- Here goes the result
    res.status(200).send(result);
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM