【发布时间】:2023-03-19 15:08:01
【问题描述】:
我的程序中有一个使用多用户支持的简单错误。我正在使用 knex 构建 sql 查询,并且我有一个描述场景的伪代码:
const value = queryBuilder().readDataFromTheDatabase();//executes this
//do some other work and get value
queryBuilder.writeValueToTheDatabase(updateValue(value));
这段代码被用于某种中间件功能。如您所见,这是一种可能的竞争条件,即当多个用户访问该事物时,其中一个用户尝试在大致相同的时间执行此操作时会获得一个陈旧的值。 p>
我的解决方案
所以,我认为一个可能的解决方案是创建一个 queryBuilder 语句:
queryBuilder().readAndUpdateValueInTheDatabase();
所以,我可能不得不使用一点plpgsql。我想知道这个解决方案是否足够。语句会自动执行吗?即,当一个请求读取但未完成写入时,另一个请求是否等待读写或只是等待写入但读取陈旧值?
【问题讨论】:
-
您需要决定要实现的变体。任何一种变体都是可能的。 (1) 阻塞。一旦第一个客户端读取一行,第二个客户端将等待并在第一个客户端完成写入并释放锁后开始读取该行。如果等待时间过长,则需要实现重试逻辑。 (2) 乐观。许多客户端可以在不锁定的情况下读取同一行。当客户端写入时,它会检查同时没有人更改行并实现解决冲突的逻辑。
标签: postgresql plpgsql knex.js acid