【问题标题】:Sequelize transaction executes a rollback but database notSequelize 事务执行回滚但数据库不执行
【发布时间】:2016-02-15 07:05:03
【问题描述】:

这是 PostgreSQL 中数据库表和约束的快照:

CREATE TABLE garage (
    garage_id integer NOT NULL,
    garage_name text,
    garage_description text
);

CREATE TABLE auto (
    auto_id serial PRIMARY KEY,
    auto_name text,
    auto_description text,
    auto_price numeric(20,2),
    auto_category text,
    garage_id integer
);

ALTER TABLE ONLY auto
    ADD CONSTRAINT auto_garage_id_fkey FOREIGN KEY (gerage_id)
    REFERENCES gerage(gerage_id);

这里我使用 Sequelize 在 nodejs 中定义数据库对象:

var Auto = sequelize.define('auto', {
    auto_id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    auto_name: Sequelize.STRING,
    auto_description: Sequelize.STRING,
    auto_price: Sequelize.NUMERIC,
    auto_category: Sequelize.STRING,
    garage_id: Sequelize.INTEGER
}, {freezeTableName: true,
        tableName: "auto",
        timestamps: false,
        paranoid: false,
        underscored: true});

function createAutos(auto_1,auto_2){
    return sequelize.transaction().then(function(t){
        return Auto.create(auto_1, 
            {fields: ['auto_name', 'auto_description', 'auto_price', 'auto_category', 'garage_id']},
            {transaction: t}
        ).then(function(){ 
            return Auto.create(auto_2, 
                {fields: ['auto_name', 'auto_description', 'auto_price', 'auto_category', 'garage_id']},
                {transaction: t});
        }).then(function(){
            t.commit();
        }).catch(function(err){
            t.rollback();
        });
    });
}

这里我执行下面的方法来测试事务性createAutos():

createAutos({
    "auto_name": 'bmw',
    "auto_description": 'sport',
    "auto_price":4.95,
    "auto_category": 'luxes',
    "garage_id": 1 // Exists in the database
},{
    "auto_name": 'SSSS',
    "auto_description": 'sport',
    "auto_price":4.95,
    "auto_category": 'luxes',
    "garage_id": 200 // Doesn't exist in the database.
});

执行时,我可以在控制台看到如下输出日志:

Executing (bf8cb998-657b-49b7-b29e-957bcf770b40): START TRANSACTION;
Executing (bf8cb998-657b-49b7-b29e-957bcf770b40): SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Executing (bf8cb998-657b-49b7-b29e-957bcf770b40): SET autocommit = 1;
Executing (default): INSERT INTO "auto" ("auto_name","auto_description","auto_price","auto_category","garage_id") VALUES ('bmw','sport',4.95,'luxes',1) RETURNING *;
Executing (default): INSERT INTO "auto" ("auto_name","auto_description","auto_price","auto_category","garage_id") VALUES ('SSSS','sport',4.95,'luxes',200) RETURNING *;
Executing (bf8cb998-657b-49b7-b29e-957bcf770b40): ROLLBACK;

但是在数据库中第一个自动“bmw”被写入,尽管整个事务的 ROLLBACK。

我使用 PostgreSQL 9.3.10、Ubuntu、MySQL 5.5.46、sequelize 3.13.0 和 3.0.0 测试了该程序

有没有人注意到这里的代码有错误或者是错误...?

【问题讨论】:

  • SET autocommit = 1;有没有原因

标签: mysql node.js postgresql transactions sequelize.js


【解决方案1】:

在您的输出日志中,我们可以看到两个事务,一个是 bf8cb998-657b-49b7-b29e-957bcf770b40,另一个是 Default。第一个回滚,第二个不回滚,这就是您插入的位置。

您尝试将事务传递给 Create 函数,但 Sequelize 似乎没有得到它。一些版本之前,交易的语法发生了变化,你可以尝试将'transaction:t'属性放在第二个对象而不是第三个对象中吗?像这样的:

Auto.create(auto_1, 
        {fields: ['auto_name', 'auto_description', 'auto_price', 'auto_category', 'garage_id'],
        transaction: t}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-15
    • 2017-04-10
    • 2021-02-11
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 2013-06-01
    • 2014-03-19
    相关资源
    最近更新 更多