乐观锁定队列



我正在使用PostgreSQL作为数据库在Node.js中编写一个应用程序。但我有一些问题。我有一个表格,其中包含有关区域中资源的信息:

CREATE TABLE regions_indexes
(
  id integer NOT NULL,
  resource_type integer NOT NULL,
  current_resource integer,
  maximum_resource integer,
  CONSTRAINT regions_indexes_pkey PRIMARY KEY (id, resource_type)
)

用户单击按钮,应用程序根据current_resource计算各种参数,然后执行current_resource - $calc_value。因为我使用交易可能非常一致。但是在过程计算中可能会有一些错误,我们需要重复计算。现在我正在使用选择...用于使用current_resource锁定行的更新。如果当前值current_resource非常重要,并且首先单击的用户应使用最大可用current_resource,我如何使用乐观锁定在没有锁定的情况下做到这一点。换句话说,我应该为current_resource实现 acess 队列。

对于乐观锁定,您需要定义一些方法来检查自上次看到行以来是否发生了变化。例如,让我们添加另一个标识符:

alter table regions_indexes add version_id integer default 1 not null;

现在,应用程序读取一些行,向用户显示数据并等待单击按钮。我们必须记住我们得到version_id的价值。

单击按钮后,执行所有必要的计算。准备好更新行时,锁定该行并检查version_id是否未更改。如果没有,请递增version_id并提交。如果有,运气不好---你需要告诉用户重复操作,因为有人跑过他。

它可能看起来像这样(在伪代码中):

-- remember version_id
select *
from regions_indexes
where id = ... and resource_type = ...;
-- wait for user click
-- you can wait for a long time, because no lock is yet acquired
...
update regions_indexes
set current_resource = current_resource - ..., version_id = version_id + 1
where id = ... and resource_type = ...
returning version_id;
if new_version_id = old_version_id + 1 then
  -- success, commit
else 
  -- fail, rollback
end if;

但是乐观锁定在高并发的情况下效果不佳。当冲突不罕见时,您必须经常重新启动事务。

最新更新