Innodb事务

69 阅读3分钟

目录

1.抛出问题

2.知识回顾

MVCC多版本并发原理

MVCC多版本并发原理

3.解答问题

4.参考文献

1.抛出问题

创建一张测试用的表dept:

CREATE TABLE `dept` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
 
  `no` int(11) not null,

  `name` varchar(20) DEFAULT NULL,

  PRIMARY KEY (`id`),

  index(no)

) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8

insert into dept(no, name) values(1, "后勤部")

1.事务1的查询Q1 和 查询Q2返回的结果分别是什么?

事务1事务2
beginbegin
select * from dept /** Q1 */点击展开内容(1,1,"后勤部")
-insert into dept(no, name) values(2, "研发部")
-commit
select * from dept /** Q2 */点击展开内容(1,1,"后勤部")
commit

2.事务1的查询Q1 和 查询Q2返回的结果分别是什么?

事务1事务2
beginbegin
select * from dept /** Q1 */点击展开内容(1,1,"后勤部")
-insert into dept(no, name) values(2, "研发部")
-commit
select * from dept for update /** Q2 */点击展开内容(1,1,"后勤部")(2,2,"研发部")
commit

3.事务1的查询Q1 和 查询Q2返回的结果分别是什么?

事务1事务2事务3
beginbeginbegin
-insert into dept(no, name) values(2, "研发部")-
-commit-
select * from dept /** Q1 */点击展开内容(1,1,"后勤部")(2,2,"研发部")-
-update dept set name="后勤部1" where no=1;
-commit
select * from dept /** Q2 */点击展开内容(1,1,"后勤部")(2,2,"研发部")
commit

4.事务1的查询Q1 和 查询Q2返回的结果分别是什么?

事务1事务2
beginbegin
select * from dept /** Q1 */查询结果(1,1,"后勤部")-
-insert into dept(no, name) values(2, "研发部")
-commit
update dept set name="后勤新部" where no=1;
select * from dept /** Q2 /查询结果(1,1,"后勤新部")select * from dept for update /* Q3 */查询结果(1,1,"后勤新部")(2,2, "研发部")
commit

5.事务1的查询Q1 和 查询Q2返回的结果分别是什么?[insert update delete select 加锁 todo ]

事务1事务2事务3
beginbeginbegin
select * from dept where no=1 for update ; /** Q1 */-
-insert into dept(no, name) values(3, "测试部")insert into dept(no, name) values(4, "研发部")
commitcommitcommit
select * from dept /** Q2 */
commit

2.知识回顾

image.png

MVCC多版本并发原理

  • 快照读: 简单的select操作,属于快照读,不加锁。(当然,也有例外,下面会分析)

    • select * from table where ?;
  • 当前读: 特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。

    • select * from table where ? lock in share mode;
    • select * from table where ? for update;
    • insert into table values (…);
    • update table set ? where ?;
    • delete from table where ?;

3.解答问题

返回第1节看答案

如果是唯一索引,则selec for update,update, delete只加行锁;在普通索引列上,只要加锁,都会产生间隙锁,这跟唯一索引不一样

RR级别下,事务开始后,第一个select 语句会创建readview,整个事务存在期间都用这个视图;RC级别下,每个sql执行都会创建一个readview视图;

4.参考文献

MySQL的可重复读级别能解决幻读吗

Innodb 中 RR 隔离级别能否防止幻读?

Innodb中的事务隔离级别和锁的关系

【MySQL】当前读、快照读、MVCC

www.huaweicloud.com/articles/f5…