一架梯子,一头程序猿,仰望星空!
MySQL性能优化面试题 > 内容正文

如何通过SQL加共享锁和排他锁?


问题简答

通过在SQL语句后面追加LOCK IN SHARE MODE和FOR UPDATE实现加锁操作。
1.加共享锁:SELECT .... LOCK IN SHARE MODE
2.加排他锁:SELECT .... FOR UPDATE;

问题详解:

加共享锁

SELECT * FROM orders WHERE order_id = 1 LOCK IN SHARE MODE;

加排他锁

SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;

加锁应用例子

假设存在accounts账号表,表包含id(用户id)、balance(余额),下面我们通过加锁控制余额加减计算,完成账号转账。

START TRANSACTION; -- 开启事务

-- 对用户 1 进行加排他锁,保证转账操作的原子性和独占性
SELECT balance FROM accounts WHERE id = 1 FOR UPDATE;

-- 对用户 2 进行加排他锁,防止并发写操作
SELECT balance FROM accounts WHERE id = 2 FOR UPDATE;

-- 更新用户 1 的余额
UPDATE accounts SET balance = balance - 50 WHERE id = 1;

-- 更新用户 2 的余额
UPDATE accounts SET balance = balance + 50 WHERE id = 2;

COMMIT; -- 提交事务,释放锁

提示:这些加锁语句只能用于事务中,且只对当前事务有效。另外,加锁会降低并发性能,需要在确实需要保证数据一致性时使用。