防止Postgres中的冲突更新

问题描述 投票:2回答:1

我有一张"users"表,其中"state"列是jsonb。用于更新该状态的逻辑是复杂的并且以“真实”编程语言(例如,JavaScript)实现。

我有多个服务器提供用于更新状态的API。这些服务器之间的负载平衡是不确定的,因此更新请求可能并不总是发送到同一服务器。

API将获取当前状态(SELECT),运行函数更新它(updateState),然后用结果更新数据库(UPDATE)。

它可能看起来像这样:

const updateHandler = async (id) =>
  const { state } = await db.one(
    `SELECT * FROM users WHERE id = $<id> LIMIT 1`, 
    { id });

  const nextState = updateState(state);

  await db.query(
    `UPDATE users SET state = $<nextState> WHERE id = $<id>`, 
    { id, nextState });
});

因为我有多个服务器,所以我想确保在状态更新时,它是在已经存在的updateState值上调用state的结果。如果另一台服务器已在执行更新,则每台服务器都必须排队(或者可能抛出错误)。

这样做的最佳策略是什么?

javascript database postgresql transactional
1个回答
3
投票

使用Optimistic Locking Pattern,您只需检查当前状态以验证您的交易

UPDATE users
SET    state = $<nextState>
WHERE  id = $<id> and state=$<currentState>

检查nb行更新以检测冲突:

  • 1行=>没关系
  • 0行=>你有冲突(另一个进程已经更新了相同的id数据)
© www.soinside.com 2019 - 2024. All rights reserved.