MySQL基础篇(06):事务管理,锁机制案例详解 (2)

InnoDB与MyISAM的最大不同有两点:一是支持事务TRANSACTION,二是采用了行级锁。行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来新问题:并发,死锁等。

共享锁:又称读锁。允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。若事务T对数据对象A加上共享锁,则事务T可以读A但不能修改A,其他事务只能再对A加共享锁,而不能加写锁,直到T释放A上的共享锁。这保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

排他锁:又称写锁。允许获取排他锁的事务更新数据,阻止其他事务取得相同的资源的共享读锁和排他锁。若事务T对数据对象A加上写锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的写锁。

3、验证案例

基础表结构

CREATE TABLE `dc_user_in01` ( `id` int(11) DEFAULT NULL COMMENT 'id', `user_name` varchar(20) DEFAULT NULL COMMENT '用户名', `tell_phone` varchar(20) DEFAULT NULL COMMENT '手机号' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'; CREATE TABLE `dc_user_in02` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `user_name` varchar(20) DEFAULT NULL COMMENT '用户名', `tell_phone` varchar(20) DEFAULT NULL COMMENT '手机号', PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='用户表';

注意结构:表dc_user_in01主键没有索引。表dc_user_in02主键有索引,但是都使用INNODB存储引擎,下面验证案例会有不同。

无索引结构表

MySQL基础篇(06):事务管理,锁机制案例详解

会话窗口一

-- 1、关闭自动提交 SET AUTOCOMMIT = 0 ; -- 2、查询id=1,OK SELECT * FROM dc_user_in01 WHERE id=1 ; -- 3、添加写锁失败 SELECT * FROM dc_user_in01 WHERE id=1 FOR UPDATE ; -- 4、恢复事务提交 SET AUTOCOMMIT = 1 ;

会话窗口二

-- 1、关闭自动提交 SET AUTOCOMMIT = 0 ; -- 2、查询id=2,OK SELECT * FROM dc_user_in01 WHERE id=2 ; -- 3、写入失败(等待) INSERT INTO dc_user_in01 (id,user_name,tell_phone) VALUES (3,'lock01','13267788998'); -- 4、写锁失败(等待) SELECT * FROM dc_user_in01 WHERE id=2 FOR UPDATE ; -- 5、恢复事务提交 SET AUTOCOMMIT=1 ;

索引结构表

MySQL基础篇(06):事务管理,锁机制案例详解

会话窗口一

-- 1、关闭自动提交 SET AUTOCOMMIT = 0 ; -- 2、查询id=1,OK SELECT * FROM dc_user_in02 WHERE id=1 ; -- 3、添加写锁成功 SELECT * FROM dc_user_in02 WHERE id=1 FOR UPDATE ; -- 执行到这里,再执行窗口2 -- 4、恢复事务提交 SET AUTOCOMMIT = 1 ;

会话窗口二

-- 1、关闭自动提交 SET AUTOCOMMIT = 0 ; -- 2、查询id=2,OK SELECT * FROM dc_user_in02 WHERE id=2 ; -- 3、查询id=1,OK,加读锁 SELECT * FROM dc_user_in02 WHERE id=1 ; -- 4、写入成功 INSERT INTO dc_user_in02 (user_name,tell_phone) VALUES ('lock01','13267788998'); -- 5、加写锁成功,id为2的 SELECT * FROM dc_user_in02 WHERE id=2 FOR UPDATE ; -- 6、加写锁失败(等待),占用id为1的 SELECT * FROM dc_user_in02 WHERE id=1 FOR UPDATE ; -- 7、恢复事务提交 SET AUTOCOMMIT=1 ;

索引失效问题

这里要注意索引是否被使用问题,在很多查询中,可能因为种种原因导致索引不执行。

explain SELECT * FROM dc_user_in02 WHERE id=1 ;

查询锁争用

show status like 'innodb_row_lock%';

Innodb_row_lock_waits和Innodb_row_lock_time_avg的值越大,锁争用情况越严重,效率则越低下。

4、Next-Key锁

官方文档说明

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywjzy.html