关于锁

Author Avatar
Marmot 5月 15, 2019
  • 在其它设备中阅读本文章

场景1:

出售商品对时候,可能会两个人同时对同一商品下单,虽然订单生成和商品状态的修改可以执行原子操作,但是可能会导致对同一商品同时执行了两个原子操作
ex:大学兼职对时候,遇到热门电影上映时,两个顾客同时购买了同一座位

解决方法:使用行锁

可以执行

1
SELECT * FROM TABLE_NAME WHERE FOR UPDATE;

来对行进行锁定,另外的线程执行 select for update 就会出现阻塞,直到原线程 commit 或 rollback。
在Django中可以使用 select_for_update 来对行进行锁定


场景2

创建一个活动,活动编号需要在已有的活动编号上+1,但是自增字段已经用于主键了(为什么不直接用主键,为也不知道)
在并发较高的情况下,两个人同时创建活动,就可能出现同一活动编号

解决方法:使用表锁

1
2
3
LOCK TABLES `TABLE_NAME` WRITE;
-- do something
UNLOCK TABLES;

当一个线程锁定表时,禁止了另外一个线程对表进行读写,直到主线程完成,才释放锁

为什么还要禁止读?

两个线程同时读到 max=100,一个先commit 101,释放锁,然后第二个还是 commit 101 依然会导致错误的产生
所以把读也一起禁止了,直到 commit 101 之后,第二个线程才读取,就正确读取到 max=101,commit 102了