显式锁select for update 用法
两个事务操作:
set autocommit=off;
A:
begin;
select * from students where id=1 for update;
B:
begin;
select * from students where id=1;
显示结果(直接查询,无需获得锁)
select * from students;
显示结果
select * from students where id=2 for update ;
显示结果
select * from students where id=1 for update;
等待(事务A提交后才会获得该行行锁)
案例:
转账操作中需要判断余额是否足够
begin;
select balance from account where id=1; ①
(对余额进行判断,余额不做的不更新操作)
update account set balance=balance-100 where id=1; ②
update account set balance=balance+100 where id=2;
commit;
多线程下,会有多个事务并发访问数据库。
假设余额150,事务a可以执行到①判断余额充足,切换线程执行事务b到①并判断余额充足,最后都提交后,id为1的账户余额为-50;所以必须让整个事务操作保持原子性。
修改①为:select balance from account where id=1 for update;对该记录加行锁。当事务a执行完提交释放行锁时事务b才能获得行锁 再查询判断。