1.悲观锁
1.1 实现
1.1.1 mysql设置
使用悲观锁,必须关闭mysql的自动提交,set autocommit = 0 ,mysql默认使用自动提交模式。
1.1.2 sql语句
#1:查出商品数量select quantity from goods where id = 100 for update;#2:根据商品信息生成订单insert into orders(id,goods_id) values(null,100);#3:修改商品的库存update goods set quantity = quantity-1 where id = 100;
select...for update是mysql提供的实现悲观锁的方式。
2.乐观锁
乐观锁相对悲观锁而言,它认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测。
2.1 实现
2.1.1 版本号
利用数据版本号机制是乐观锁最常用的一种实现方式。一般通过为数据库表增加一个数字类型的“version”字段,当读取数据时,将version字段的值一同读出,数据每更新一次,version值+1。当我们提交更新的时候,判断数据表对应的当前版本信息与第一次取出来的version值是否一致,一致则更新,否则更新失败。
#1:查询商品数量和versionselect (quantity,version) from goods where id = 100;#2:根据商品信息生成订单insert into orders (id,goods_id) values(null,100);#3:修改商品的库存update goods set quantity = quantity -1,version = version +1 where id = 100 and version = #上面查询的version
2.1.2 秒杀系统的思路
<?php$res = DB::update('update goods set quantity = quantity - 1 where id = ? and quantity -1 >= 0', [1]);if ($res) {DB::insert('insert into orders (goods_id,price) values (?,?)', [1,4999]);DB::insert('insert into logs (content,create_at) values (?,?)', ['抢购成功',date('Y-m-d H:i:s')]);}else{DB::insert('insert into logs (content,create_at) values (?,?)', ['抢购失败',date('Y-m-d H:i:s')]);}
