一、死锁模拟
1)创建表base_account_item 并且插入两条数据
CREATE TABLE base_account_item (
id INT(11) NOT NULL,
account_item_name VARCHAR(50) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO base_account_item (id, account_item_name) VALUES (1, '本金1');
INSERT INTO base_account_item (id, account_item_name) VALUES (2, '本金2');
2)开启一个客户端 执行事务A
# 事务A
START TRANSACTION;
SELECT * FROM base_account_item WHERE id = 1 FOR UPDATE;
-- 不提交或回滚,保持连接开启
SELECT SLEEP(5);
SELECT * FROM base_account_item WHERE id = 2 FOR UPDATE;
3)开启另外一个客户端执行事务B
# 事务B
START TRANSACTION;
SELECT * FROM base_account_item WHERE id = 2 FOR UPDATE;
-- 等待连接
SELECT SLEEP(5);
SELECT * FROM base_account_item WHERE id = 1 FOR UPDATE;
4)产生死锁
二、总结
1)mysql死亡是否会自动释放及死锁的定义
MySQL会自动检测事务死锁并立即回滚其中一个事务,并返回一个错误。 死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象。若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程。
2)如何避免死锁
- 优化SQL语句,减少锁定时间,避免相互等待锁的代码
- 调整事务隔离级别。
- 减少事务的长度。
- 尽量避免在事务中进行大量的更新操作。