行锁定防止超卖

本文转载自:http://www.ddhigh.com/2014/12/mysql-row-lock/

大家可能都有这样一种感觉,Web程序在本地调试的时候一切正常,放到线上也基本是正常,但是偶尔会有数据错误的情况,这种情况在订单系统中特别常见,因为大部分的订单状态更新都是有两个路径(浏览器跳转和支付服务器的异步推送消息),当然,最终数据要以异步结果为准,但是问题是,浏览器跳转也需要更新订单状态,当这两种方式在很短的时间内同时到达数据库时(一般在一秒内),如果数据库没有加锁,那这个订单会被处理两次。

说到建立数据表时,涉及到支付的,都要用InnoDB引擎,该引擎支持行锁,支持事务,外键。

文章开始的解决办法就是采用InnoDB对要操作的数据行进行锁定。

数据表结构

订单ID(主键) 订单金额 订单状态

这里为了简单就只设置了几个核心字段,接下来通过两方面来更新订单。

  1. 浏览器的跳转

 
 
  1. BEGIN;
  2. SELECT * FROM `orders` WHERE `order_id`=100 FOR UPDATE;
  3. //业务逻辑
  4. COMMIT;

核心语句就三条,一条条来解释

1.BEGIN 手动开启事务(行锁只对开启事务的查询起作用)

2.FOR UPDATE 独占写(成功获得锁后,只有当前进程能够更新该纪录,其他进程如果需要更新该记录,则需进行“锁等待”)

3.COMMIT 提交处理

 

 2.  支付服务器异步推送

    处理方式跟浏览器的一样,只要加了行锁就没问题。

这样不管多大的并发过来,因为有了行锁,不会出现问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值