I have a problem with transactions.
This is my case :
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
- 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, becausesequelize.transaction
also returns a promise and that is when the transaction is finished- you may want to call
t.rollback()
instead of just referencing it ast.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.