防止Postgres中发生冲突的更新

时间:2018-09-18 09:37:05

标签: javascript database postgresql transactional

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

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

API将获取当前状态(jsonb),运行该函数以对其进行更新(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的结果。如果另一台服务器已经在执行更新,则每台服务器都必须排队(或者抛出错误)。

执行此操作的最佳策略是什么?

1 个答案:

答案 0 :(得分:3)

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

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

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

  • 1行=>没关系
  • 0行=>您有冲突(另一个进程有 已经更新了相同的ID数据)