PostgreSQL: select for update实战

发布时间 2023-12-05 14:50:56作者: 胸怀丶若谷

场景

需要获取用户申请的流水号,其值记录在number_of_form表中。但当多个用户同时申请时,会出现单号重复的情况,现在需要保证单据号码的一致性

image

解决方案

以我搜寻来看,大体有两种做法。

  1. 悲观锁:总是假设最坏的情况,也就是每次拿数据的时候,都认为别人会修改,所以每次拿数据,都会对符合条件的数据进行加锁。

  2. 乐观锁: 不会对符合条件的数据进行加锁,但在写入之前,会对数据进行一次校验。看获取的数据和在数据库中的数据是否一致。

实际做法(选择悲观锁)

窗口1

SELECT *
FROM number_of_form
WHERE year = '24'
  AND month = '02' FOR UPDATE;

UPDATE number_of_form
SET number=3
WHERE uuid = {{your_uuid}};

另外需要注意的是,我再DataGrip中,将提交设置为了手动。这样才能在执行的时候,触发另一个语句。

image
此时,数据如下所示

image

同步进行

窗口2

UPDATE number_of_form SET number=(
    SELECT number + 1 as number from number_of_form WHERE year = '24'
  AND month = '02' FOR UPDATE
    )WHERE uuid='{{your_uuid}}';

执行如上语句,语句会处在加载的状态。

回到第一条语句的编辑器,按下提交按钮。
image

此时窗口2会完成写入语句。其结果如下所示
image

执行成功

参考链接

https://zhuanlan.zhihu.com/p/626926704
https://segmentfault.com/a/1190000023045909

关于阻塞

https://blog.csdn.net/u014240299/article/details/120471319
https://blog.csdn.net/weixin_33704234/article/details/86085336