navicat
mysql
使用navicat客户端工具连接上测试的mysql数据库,新建一个测试表CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号', `login_name` varchar(50) NOT NULL COMMENT '用户名', `pwd` varchar(50) NOT NULL COMMENT '密码', `nick_name` varchar(90) DEFAULT NULL COMMENT '用户昵称', `usable` int(11) NOT NULL DEFAULT '1' COMMENT '是否可用 0:不可用;1:可用', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `last_login_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后登录时间', PRIMARY KEY (`id`), UNIQUE KEY `login_name` (`login_name`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='用户表';数据如图所示
打开一个新的会话窗口,执行以下语句set autocommit=0; --关闭自动提交SELECT * from t_user t where t.id='1' FOR UPDATE; 给id为1的数据行添加行锁
打开另一个新的会话窗口,执行以下语句set autocommit=0; --关闭自动提交SELECT * from t_user t where t.id='2' FOR UPDATE; 给id为2的数据行添加行锁
这个时候,2和3步骤各持了一把锁。下面开始在会话一执行SELECT * from t_user t where t.id='2' FOR UPDATE; 会出现锁等待的情况
在会话二里执行SELECT * from t_user t where t.id='1' FOR UPDATE; 则出现了死锁提示:ERROR 1213 : Deadlock found when trying to get lock; try restarting transactionmysql自动检测到了两个会话互相等待锁的情况,则把最后一个会话做了回滚操作
可以通过以下三个语句来查询被打开的表,正在执行的任务列表和开启的事务show OPEN TABLES where In_use > 0;show processlist; -- kill杀死进程id(id列)SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;-- kill杀死进程id(trx_mysql_thread_id列)
对于高并发的系统,如果锁控制不好,很容易就会出现死锁,数据库出现死锁会导致应用系统功能无响应,甚至服务崩溃。