我正在開發一個節點專案,我在其中匯入了用于資料庫操作的 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')
我在這里做錯了什么還是有更好的方法來處理上述情況?
uj5u.com熱心網友回復:
如果您更新行而不是洗掉它們并重新創建它們,這可能會更容易。在這種情況下,您可以依靠行鎖來防止并發更新。
uj5u.com熱心網友回復:
使用INSERT ... ON CONFLICT以“UPSERT”傳入行。這是原子的,沒有競爭條件。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/352984.html
標籤:节点.js 数据库 PostgreSQL 竞争条件
上一篇:兩列的SQL唯一組合,反之亦然
