1、 共享锁和共享数是相互兼容可以共存的,但是共享锁只能查询,不能修改,只有事物提交后才可以修改数据;
测试:打开两个测试窗口(这里用的是Navicat工具),窗口1和窗口2开启事务,此时两个窗口查询表数据都是可以成功的
-- 第1步、窗口1开启事物 START TRANSACTION; -- 第2步、查询数据并添加共享锁 SELECT * FROM city LOCK IN SHARE MODE; -- 第3步、窗口2开启事物 START TRANSACTION; -- 第4步、查询数据并添加共享锁 SELECT * FROM city LOCK IN SHARE MODE;
2、InnoDB默认加行锁;
-- 第1步、窗口1开启事物 START TRANSACTION; -- 第2步、窗口1查询数据并添加共享锁 SELECT * FROM city WHERE id = 1 LOCK IN SHARE MODE; -- 第3步、窗口2开启事物 START TRANSACTION; -- 第4步、窗口2修改数据(此时修改数据成功,因为id是主键索引,窗口1加的是行锁,只锁了id为1的那行数据,对此次修改的id为2的数据没有影响) UPDATE city SET name = '北京' WHERE id = 2 -- 第5步、窗口2提交事物(修改后提交事务了,修改的数据才能持久化,才是真正保存到数据库) COMMIT; -- 第6步、窗口1提交事物 COMMIT;
3、InnoDB引擎如果不采用带索引的列加锁的话,那么加的就是表锁;
测试:窗口1和窗口2开启事务,窗口1查询city表,然后窗口2修改city表中的数据,此时修改一直处于等待状态,因为没有采用带索引的列加锁,此时表是锁死的,无法修改,
只有当窗口1提交事务后,窗口2的修改才能成功。
-- 第1步、窗口1开启事物 START TRANSACTION; -- 第2步、窗口1查询数据并添加共享锁 SELECT * FROM city LOCK IN SHARE MODE; -- 第5步、窗口1提交事物 COMMIT; -- 第3步、窗口2开启事物 START TRANSACTION; -- 第4步、窗口2修改数据(此时修改数据时一直处于等待状态,只有窗口1提交事务后,修改才能成功,因为窗口1没有使用带索引的列加锁,此时加的就是表锁,锁住整张表) UPDATE city SET name = '深圳' WHERE id = 1 -- 第6步、窗口2提交事物(不提交事务修改只是临时的,只有提交了事务修改才是持久化的) COMMIT;