关于锁
场景1:
出售商品对时候,可能会两个人同时对同一商品下单,虽然订单生成和商品状态的修改可以执行原子操作,但是可能会导致对同一商品同时执行了两个原子操作
ex:大学兼职对时候,遇到热门电影上映时,两个顾客同时购买了同一座位
解决方法:使用行锁
可以执行1
SELECT * FROM TABLE_NAME WHERE FOR UPDATE;
来对行进行锁定,另外的线程执行 select for update 就会出现阻塞,直到原线程 commit 或 rollback。
在Django中可以使用 select_for_update 来对行进行锁定
场景2
创建一个活动,活动编号需要在已有的活动编号上+1,但是自增字段已经用于主键了(为什么不直接用主键,为也不知道)
在并发较高的情况下,两个人同时创建活动,就可能出现同一活动编号
解决方法:使用表锁
1 | LOCK TABLES `TABLE_NAME` WRITE; |
当一个线程锁定表时,禁止了另外一个线程对表进行读写,直到主线程完成,才释放锁
为什么还要禁止读?
两个线程同时读到 max=100,一个先commit 101,释放锁,然后第二个还是 commit 101 依然会导致错误的产生
所以把读也一起禁止了,直到 commit 101 之后,第二个线程才读取,就正确读取到 max=101,commit 102了