【问题标题】:NodeJS - Which layer should I roll back the transaction with multiple inserts?NodeJS - 我应该在哪一层回滚具有多个插入的事务?
【发布时间】:2021-09-30 12:09:55
【问题描述】:

我在我的 API 中使用控制器层/服务层/存储库层和 Postgres 数据库(我使用的是 node-postgres)。

在给定的服务中,在插入某些信息A之前,我需要在数据库的其他表中插入其他信息。但是,如果其中一个插入有问题,我想回滚事务。在 node-postgres 中,回滚操作如下:

const { Pool } = require('pg')
const pool = new Pool()
;(async () => {
  // note: we don't try/catch this because if connecting throws an exception
  // we don't need to dispose of the client (it will be undefined)
  const client = await pool.connect()
  try {
    await client.query('BEGIN')
    const queryText = 'INSERT INTO users(name) VALUES($1) RETURNING id'
    const res = await client.query(queryText, ['brianc'])
    const insertPhotoText = 'INSERT INTO photos(user_id, photo_url) VALUES ($1, $2)'
    const insertPhotoValues = [res.rows[0].id, 's3.bucket.foo']
    await client.query(insertPhotoText, insertPhotoValues)
    await client.query('COMMIT')
  } catch (e) {
    await client.query('ROLLBACK')
    throw e
  } finally {
    client.release()
  }
})().catch(e => console.error(e.stack))

在存储层调用数据库连接。但是,回滚情况只会发生在服务层。我该如何解决这种情况,由于架构原因,我不能直接在服务层调用数据库连接?我的架构有问题吗?

【问题讨论】:

    标签: node.js database postgresql architecture


    【解决方案1】:

    完成此任务的最简单方法是将所有相关事务放入存储库层中的单个方法中。这通常是“OK”的,因为它们基本上都是一个事务。

    如果您需要支持分布式事务,最好使用unit of work pattern 来实现对各种事务的保持,并回滚整个工作单元。

    【讨论】:

    • 如果其他信息的各种插入到您的表中取决于一条信息是否存在,这是否有效?例如:我有 Product 表和 Items 表。如果 Product 已经存在,则不需要插入,否则插入。之后,使用产品 ID,我在 Items 中输入信息。将这种规则合并到 Repository Layer 中是否有意义?
    • 是的,这一切都与数据存储/检索细节有关。不要放入业务逻辑,但纯数据库逻辑就可以了。考虑一下,如果您将其存储在具有 JSON 文件存储而不是 RDMS 之类的其他存储介质中,则不需要在存储库之外提取多表逻辑......另外,仅供参考,请采取看看 upsert 而不是插入/更新逻辑:wiki.postgresql.org/wiki/UPSERT
    • 不错!我相信这足以解决我的问题。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多