简体   繁体   English

PostgreSQL的Sequelize.js事务问题

[英]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 我将node.js用作sequelize.js的后端
  • I use angular as my frontend 我使用angular作为前端
  • I use PostgreSQL as my Database 我使用PostgreSQL作为数据库
  • 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. 因此,在第一个服务中,我先执行UPDATE ,然后执行INSERT ,如果流程中有错误,我将使用事务回滚。 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. 在angular中,我将服务称为“更新和插入”(上面),完成后,我将调用另一个服务,该服务查询要更新和插入的表。

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. 注意:我尝试添加t.commit,但结果是相同的。

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: 来自sequelize slack的@florin回答了我,所以我把他的回答放在这里:

http://docs.sequelizejs.com/manual/tutorial/transactions.html 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 这意味着你应该移动.then在端线,因为sequelize.transaction也返回一个承诺,那就是当交易完成
  2. you may want to call t.rollback() instead of just referencing it as t.rollback without the parentheses 您可能要调用t.rollback()而不是仅将其引用为不带括号的t.rollback

So, the answer was that I have to put the result in the transaction .then like: 因此,答案是我必须将结果放入事务中.then像:

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);
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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