在事务执行过程中,如果有加锁操作,这个锁需要等事务提交时释放。
时间线 | 事务1 (T1) | 事务2(T2) |
---|---|---|
t1 | BEGIN; | BEGIN; |
t2 | UPDATE lockdemo SET state = '666' WHERE id = 2; | |
t3 | UPDATE lockdemo SET state = '22' WHERE id = 2; | |
t.. | SELECT * FROM lockdemo; | SELECT * FROM lockdemo; |
t.. | commit; | commit; |
事务1在t2时刻先执行更新操作,它就会一直持有id=2的锁直到commit;事务2在t3时刻获取会失败。
SQL
BEGIN;
UPDATE lockdemo SET state = '666' WHERE id = 2;
SELECT * FROM lockdemo;
COMMIT;
BEGIN;
UPDATE lockdemo SET state = '22' WHERE id = 2;
SELECT * FROM lockdemo;
COMMIT;
死锁
死锁是指两个或多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象.当多个事务试图以不同的顺序锁定资源时,就可能会产生死锁,多个事务同时锁定同一个资源时,也会产生死锁。
例如:
事务1:
start transaction;
update stock_price set close = 45.50 where stock_id = 4 and date = '2017-4-26';
update stock_price set close = 19.80 where stock_id = 3 and date = '2017-4-27';
commit;
事务2:
start transaction;
update stock_price set high = 20.10 where stock_id = 3 and date = '2017-4-27';
update stock_price set high = 47.20 where stock_id = 4 and date = '2017-4-26';
commit;
如果凑巧,两个事务均执行了第一条update语句,同时锁定了该资源,当尝试执行第二条update语句的时候,去发现资源已经被锁定,两个事务都等待对方释放锁,则陷入死循环,形成死锁。
为了解决这种问题,数据库系统实现了各种死锁检测和死锁超时机制.比如InnoDB存储引擎目前的处理方法是将持有最少级排他锁的事务进行回滚.