mysql 死锁解决


查看锁记录等待时间: SHOW VARIABLES LIKE 'innodb_lock_wait_timeout'; 把超时等待时间修改为5秒: SET innodb_lock_wait_timeout=5;   注意行锁和表锁:mysql innodb存储引擎支持行锁 select 不会锁表,已经产生锁的表也不影响查询,除非select xxx for update;因为 for update会请求加锁 update xxx 不带where条件,锁表(已验证) update xxx where 带条件,锁指定行(必须满足where条件只要有一个条件用上索引,否则行锁变成表锁) update xxx where id in ( select id from xxx ) 带条件复杂查询,锁表(1、即使select子查询用到了索引,也会锁表;2、update连带select子查询的所有表都会加锁,加锁规则同上) update 锁表之后,如果insert是会受影响的(唯一不受影响的是select 不带for update语句) 测试方法: 打开查询编辑器: set autocommit = 0;只针对当前连接 相关测试语句 commit; 新开连接,打开查询编辑器: 相关语句   结论:不带where 条件锁表,带where条件不带索引锁表,嵌套子查询连带加锁 锁表主要针对insert update remove,基本上不影响select除非,手动加for update请求加锁   查看事务提交模式: show session variables like 'autocommit'; show global variables like 'autocommit'; Value的值为ON,表示autocommit开启。OFF表示autocommit关闭。   查看mysql存储引擎模式: SHOW ENGINES; InnoDB DEFAULT Supports transactions, row-level locking, and foreign keys     死锁1: 高并发情况下,insert 使用 where 会死锁,列如: insert into aut_sign_heartbeat ( ? ) SELECT ? FROM DUAL WHERE NOT EXISTS( SELECT id FROM aut_sign_heartbeat WHERE CRIMINAL_ID = #{criminalId} AND DEVICE_TYPE=#{deviceType} AND create_time = #{createTime} )   死锁解决: SELECT * FROM information_schema.INNODB_TRX; trx_rows_locked: 事务锁定行数 trx_rows_modified: 事务修改行数 #首先查询是否锁表 SHOW OPEN TABLES WHERE In_use > 0; #查询进程,保证拥有超级管理员权限 SHOW PROCESSLIST; #杀死进程 KILL 4503; #查看正在锁的事务 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; #查看等待锁的事务 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;