废话先不说,先上结果。
对同一条数据进行操作 !!!
一、先读后改
- 开启事务1
- 执行加共享锁的读
- 开始事务2
- 执行加排它锁的修改
二、
- 左侧的事务不提交
- 再次执行右侧的sql
三、
- 左侧事务提交
- 右侧再次执行
四、
- 右侧不提交
- 左侧再次执行
五、
- 右侧提交
- 左侧再次执行
六、
- 左侧不提交
- 右侧重新执行
七、
- 两侧全部提交
- 不加事务,各自执行sql
八、
- 左侧加事务
- 执行左侧
- 左侧提交事务
- 右侧加事务
- 执行右侧
- 右侧提交事务
结论:
lock in share mode 是共享锁
如果事务对某行数据加上共享锁之后,可进行读写操作;其他事务可以对该数据加共享锁,但不能加排他锁,且只能读数据,不能修改数据。 某个事物想进行修改数据操作,那他必须等其他事物的共享锁都释放完毕才能进行修改操作
for update 排他锁,就是行锁
如果事务对数据加上排他锁之后,则其他事务不能对该数据加任何的锁。获取排他锁的事务既能读取数据,也能修改数据。
注意:
1、普通 select 语句默认不加锁,而CUD操作默认加排他锁!!!
2、查询字段未加索引(主键索引、普通索引等)时,使用表锁
事务1获取某行数据共享锁,其他事务可以获取不同行数据的共享锁,不可以获取不同行数据的排他锁
事务1获取某行数据排他锁,其他事务不可以获取不同行数据的共享锁、排他锁
3、加索引后,两种行锁为(使用行锁):
事务1获取某行数据共享锁,其他事务可以获取不同行数据的排他锁
事务1获取某行数据排他锁,其他事务可以获取不同行数据的共享锁、排他锁
附上sql代码
-- 第一个操作窗口sql
-- DROP table t ;
CREATE TABLE t (i int(1),u int(1)) ENGINE = InnoDB;
START TRANSACTION;
INSERT INTO t (i,u) VALUES(1,1);
COMMIT;
START TRANSACTION;
SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE ;
COMMIT;
-- 第二个操作窗口sql
START TRANSACTION;
DELETE FROM t WHERE i = 1;
COMMIT;
START TRANSACTION;
SELECT * FROM t WHERE i = 1 for UPDATE;
COMMIT;
可以去参考大佬的文章:
https://blog.csdn.net/xiao__miao/article/details/106052984