【问题标题】:Call Rollback Transaction in Other function - Node+KnexJS在其他函数中调用回滚事务 - Node+KnexJS
【发布时间】:2020-03-13 20:21:49
【问题描述】:

我有一个在我的数据库中执行插入的事务,但我需要执行另一个更简单的插入,如果第二次插入出现错误,我想调用事务回滚。

await knex.transaction(async trx => {                
    const queries = []
    for(const dadoResultado of dadoResultados.dados){
        const query = app.db.raw(`
            insert into dadoResultados
                ...
            `)
            .transacting(trx)
            .catch(err => res.status(500).send(err.message))

            queries.push(query)
    }
    await Promise.all(queries)
        .then(trx.commit)
        .catch(trx.rollback)
})

await app.db.raw(`
    INSERT INTO resumoacompanhamentos (num, value)
        values (13, 50)
`)

代码修改:

try{
    await app.db(async trx => {
        for(const data of values.dados){
            await trx.raw(`
                insert into values(code_inst, money, subscription, version, first_name)
                select
                    b.code_inst,    
                    b.money
                    p.subscription,    
                    a.version,                  
                    b.first_name
                from (VALUES (${data.code_inst}, ${data.money}, ${data.first_name}) b(code_inst, money, first_name)
                inner join table_P as p
                on p.code_inst = b.code_inst
                AND p.version = b.version
                AND p.code_inst = b.code_inst
                left join table_A AS a
                on a.subscription = p.subscription
            `)        
        }

        const sum_value_final = await app.db.raw(`
            SELECT 
                SUM(money) AS money
            FROM values
                WHERE first_name = ${first_nameFile}
                AND subscription = ${values.dados[0].subscription}
        `)

        const sumValues = await sum_value_final.rows[0]

        await app.db.raw(`
            INSERT INTO resume_table (code_inst, subscription)
                values (${sumValues.dados[0].code_inst}, ${sumValues.dados[0].subscription)
        `)                            
    })
} catch(err){
    res.status(500).send(err.message);
}

错误二:

select * from (select *) - FROM 中的子查询必须有别名

【问题讨论】:

  • 起来,能帮帮我吗?

标签: node.js postgresql knex.js


【解决方案1】:

您使用了错误的交易。当您从事务处理函数返回Promise 时,您永远不应显式调用 trx.commit() / trx.rollback()。此外,您正在调用全局 knex 以获取事务连接,然后使用 app.db.raw 运行查询,这真的很奇怪......

无论如何你都在尝试这样做:

try {
  await app.db.transaction(async trx => {                
    for(const dadoResultado of dadoResultados.dados){
      await trx.raw(`
          insert into dadoResultados
          ...
      `);

    }

    await trx.raw(`
      INSERT INTO resumoacompanhamentos (num, value)
        values (13, 50)
    `)

  });
} catch (err) {
  res.status(500).send(err.message);
}

【讨论】:

  • 第二个查询的选择,基于同一事务的先前插入进行选择,考虑到如果第一个已完成,您只能执行第二个,是否可以这样做?
  • 这种方式只有在第一个查询完成后才会运行第二个。如果 for 循环中的任何查询失败,则会引发异常,并且不会运行最后一个查询。
  • 错误:select * from (select *) - FROM 中的子查询必须有别名
  • 您需要自己调试查询,我只是展示了 knex 事务的工作原理。无论如何,我绝不会建议您使用 knex raw 编写查询的方式?‍♂️祝您好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
相关资源
最近更新 更多