MySQL行锁的使用

2014年12月12日 · 26 字 · 1 分钟

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

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

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

数据表结构

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

事务SQL

BEGIN;
SELECT * FROM `orders` WHERE `order_id`=100 FOR UPDATE;

COMMIT;

释义

  1. BEGIN 手动开启事务(行锁只对开启事务的查询起作用)
  2. FOR UPDATE 独占写(成功获得锁后,只有当前进程能够更新该纪录,其他进程如果需要更新该记录,则需进行“锁等待”)
  3. COMMIT 提交处理