【发布时间】:2021-12-21 12:07:55
【问题描述】:
我正在开发一个节点项目,我在其中导入了 pg 库以进行数据库操作。我有一个 Kafka 队列,我从中获取事件并将它们存储在数据库中。我正在从 kafka 获取订单,每次更新订单时都会生成一个新事件,我需要删除旧的订单详细信息并用新的替换它们。
下面是代码
async function saveOrders(orders: Array<TransactionOnOrders>) {
const client = await pool.connect()
try {
await client.query('BEGIN')
if (orders.length) {
const deleted = await deleteOrders(client, orders[0].orderId)
logger.debug(`deleted rowCount ${deleted.rowCount} ${orders[0].orderId}`)
}
const queries = orders.map(ord => saveTransactionOnOrders(client, ord))
await Promise.all(queries)
await client.query('COMMIT')
} catch (e) {
await client.query('ROLLBACK')
throw e
} finally {
client.release()
}
}
订单更新非常频繁,我们收到大量事件,造成竞争条件,导致记录不被删除并插入额外记录。 例如:假设我们收到了 order123 的事件并且事务正在处理中,直到它完成 order123 的另一个事件,所以删除查询返回 0 行受影响,插入查询插入另一行导致 2 行应该只存在一条记录。
我曾尝试更改隔离级别,但效果不佳并导致错误
await client.query('BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ')
await client.query('BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE')
我在这里做错了什么还是有更好的方法来处理上述情况?
【问题讨论】:
-
得到一个序列化错误没什么大不了的,你只需要抓住它并重试。
标签: node.js database postgresql race-condition