您的位置:首页 > 数据库 > MySQL

Mysql事务锁行select..for update

2017-01-16 00:00 225 查看
SQL语句:

SELECT ... FOR UPDATE [OF column_list][WAIT n|NOWAIT][SKIP LOCKED];

详解:

OF 子句用于指定即将更新的列,即锁定行上的特定列。
WAIT 子句指定等待其他用户释放锁的秒数,防止无限期的等待。

示例:

SELECT * FROM 'account' FOR UPDATE

会等待行锁释放之后,返回查询结果。

SELECT * FROM 'account' FOR UPDATE NOWAIT

不等待行锁释放,提示锁冲突,不返回结果

SELECT * FROM 'account' FOR UPDATE WAIT 5

等待5秒,若行锁仍未释放,则提示锁冲突,不返回结果

SELECT * FROM 'account' FOR UPDATE SKIP LOCKED

查询返回查询结果,但忽略有行锁的记录

“使用FOR UPDATE WAIT”子句的优点如下:
  1防止无限期地等待被锁定的行;
  2允许应用程序中对锁的等待时间进行更多的控制。
  3对于交互式应用程序非常有用,因为这些用户不能等待不确定
  4 若使用了skip locked,则可以越过锁定的行,不会报告由wait n 引发的‘资源忙’异常报告

简单场景:

【钱包扣钱】事务中:

//事务
SELECT balance FROM 'account' WHERE id = 1 FROM UPDATE
//判断钱包是否大于需要扣除的金额,例如100
UPDATE 'account' SET balance = balance - 100 WHERE id =1
//提交事务

在未提交事务之前,其他人使用for update语句查询这个时候会出现被锁住,无法被读取。保证准确性

SELECT ... FOR UPDATE 的Row Lock 与Table Lock

只有「明确」的指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。

示例:

表account 其中主键为id

SELECT * FROM 'account' WHERE id='3' FOR UPDATE;

有主键,并且有此数据,row lock

SELECT * FROM 'account' WHERE id='-1' FOR UPDATE;

主键,若查无此数据,无lock

SELECT * FROM 'account' WHERE name='小树' FOR UPDATE;

无主键,table lock

SELECT * FROM 'account' WHERE id<>'3' FOR UPDATE;
SELECT * FROM 'account' WHERE id>'3' FOR UPDATE;
SELECT * FROM 'account' WHERE id LIKE '3' FOR UPDATE;

主键不明确,table lock
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: