我正在使用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。因为它可能非常简洁地使用交易。但在过程计算中可能存在一些错误,我们需要重复计算。现在我使用SELECT ... FOR UPDATE来使用current_resource来锁定行。如果current_resource的当前值非常重要,并且首先点击的用户应该使用max,那么我如何使用乐观锁定无锁定。 avalaible current_resource。换句话说,我应该为current_resource实现一个访问队列。
答案 0 :(得分:1)
对于乐观锁定,您需要定义一些方法来检查自上次查看以来行是否已更改。例如,我们只需添加另一个标识符:
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;
但乐观锁定在高并发性的情况下不能很好地工作。当冲突不常见时,您将不得不经常重启事务。