laravel电商网站怎么防止库存脏数据-减库存加锁

laravel电商网站怎么防止库存脏数据-减库存加锁--------------------------

1. 电商网站里都少不了减库存的操作,当然什么时候减各有各的处理,有的下单就减,有的发起支付就减少,有的支付完成后回调时减。对于这个减库存的时间点,因产品而已,比如秒杀类必须下单就减。

减库存时就不可避免会碰到一个用户从读取出当前库存,判断库存数量是否足够,执行减少库存(减商品表的库存、可能还需要减少商品sku表的库存)这步结事的过程中,如果有另外一个用户也读取了库存(前面的用户尚未减库存),并且也会随后减库存,此时就出现了脏读以及写脏数据了。

这里的处理一般都是加锁处理,锁可以是文件锁,也可是以数据库库锁,一般数据库锁见得多,数据库的锁里又有悲观锁和乐观锁,对于业务量不大的站,建议用悲观锁。我们这里也就只说悲观锁的处理。在减库存前的第一步是查询商品表的库存(如果有SKU再查sku表的库存)所以我们需要在查商品表库存时加锁,

如下: 2.

1,使用DB查询时: $product = DB::table('product')->where('id', $productId)->lockForUpdate()->first(); 2,使用Eloquent的MODEL查询 $product = Product::where('id', $productId)->lockforupdate()->first(); 我们都看到里了里面有一个lockForUpdata方法,这是laravel封装的,实际也很简单,就是最终的SQL就是select * from product where id= {$productId} for update,但这里要注意几点: 1,for update针对的是innodb引擎,对于myIsAM是没有这样的方法的。myisam只提供表锁,

2,上面的锁只在Transaction(事务)中才起作用。因为forupdate并不是在等待另外一句forupdate查询结束,而是在等着另外含有forupdate查询子句的事务提交或者回滚。

3,innodb是行锁,但行锁加成功与否依赖于是否是主键查询,上面的查询中id是商品表的主键,所以加锁成功,但如果换成未做索引的商品名称,就不是行锁。而是会自动转化成表锁。

4,在这步操作中执行完毕一定要执行事务提交或回滚,不然其它的forupdate就会一直在等待。mysql 中有一项配置:innodb_lock_wait_timeout=50 ,标示锁等待多少秒后,报错。

报的错误提示内容是:Lock wait timeout exceeded。此时很不好排查问题,多数业务是直接重启mysql,但这会造成数据不可逆的丢失异常。所有一定要提交或者回滚事务。

当然有一个好办法可查看是哪里没有提交或者回滚事务。在5.5中,

information_schema 库中增加了三个关于锁的表(MEMORY引擎);

innodb_trx 当前运行的所有事务innodb_locks 当前出现的锁innodb_lock_waits 锁等待的对应关系可以查看这三张表看当前事务被阻塞的情况,并结束掉死锁的事务。

本文地址:http://www.04007.cn/article/111.html 未经许可,不得转载.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值