如果事务隔离级别是默认的REPEATABLE READ , 在相同事务里的所有一致读都会读取这个事务第一次读的时候建立的快照 。
可以通过提交当前事务并在之后发出新的查询来得到新的快照
对于READ COMMITTED隔离级别 , 每个事务里的一致读都会设置并读取它自己的新快照
一致读是InnoDB在READ COMMITTED和REPEATABLE READ隔离级别下处理SELECT语句的默认模式 。
数据库的快照状态应用于事务里的SELECT语句 , 不一定应用于DML语句 。 如果插入或修改某些行然后提交该事务 , 则从另一个并发的可重复读事务会影响到这些刚提交的行 , 尽管这session查询不到它们 。
如果某个事务确实更新或删除了不同事务提交的
例子(其他session提交记录 , 原session查询不到 , 可以删除):
#sessionA
select count(name) from child where name = 'hello100';
### 返回0行
#sessionB插入两行并提交
insert into child(idname) values(100 'hello100');
insert into child(idname) values(101 'hello100');
#sessionA统计 , 返回0行
select count(name) from child where name = 'hello100';
#sessionA删除 , 尽管查询不到 , 但可以删除2行
delete from child where name = 'hello100';
### Query OK 2 rows affected (0.00 sec)
可以通过提交事务 , 然后执行SELECT或START TRANSACTION WITH CONSISTENT SNAPSHOT来更新时间点 。 这就是多版本并发控制
下面的例子 , sessionA只在B提交了插入 , 且A已提交后 , 才能看到B插入的记录
Session A Session B
SET autocommit=0; SET autocommit=0;
time
| SELECT * FROM t;
| empty set
| INSERT INTO t VALUES (1 2);
|
v SELECT * FROM t;
empty set
COMMIT;
SELECT * FROM t;
empty set
COMMIT;
SELECT * FROM t;
---------------------
| 1 | 2 |
---------------------
如果想看到数据库的最新状态 , 那么要使用READ COMMITTED隔离级别 , 或者锁定读:
InnoDB中不同SQL语句设置的锁锁定读 , UPDATE或者DELETE通常会在SQL语句处理的过程中对每个被扫描到的索引记录设置记录锁 。 它不管语句中的WHERE条件是否会排除掉行 。 InnoDB不会记得准确的WHERE条件 , 只知道哪部分索引范围被扫描 。
SELECT * FROM t FOR SHARE;
读已提交隔离级别 , 一个事务里的每个一致读都会设置并读取它自己的新快照 。 对于FOR SHARE , SELECT一直阻塞直到包含最新行的事务结束
如果搜索中使用了二级索引 , 并且索引记录锁被设置为排他的 , InnoDB也会检索出相应的聚簇索引记录并对它们设置锁 。
如果没有索引适合执行语句 , 那么MySQL必须扫描整个表来处理语句 , 表的每一行都会被锁定 , 从而也会阻塞其他用户插入到这个表中 。 所以创建好的索引 , 让查询不会扫描超过需要的行是很重要的 。
- 平时大家输入汉字时一般都习惯用拼音输入法|怎么在电脑上把不认识的字打出来
- Java|24位博主,带你了解自媒体的真相
- 华为|不同职业的人怎么选华为PC?带你对号入座
- 域名|认识松下Lumix DC-G95(G90)
- 骨传导耳机|骨传导耳机伤耳朵吗?带你一分钟了解骨传导耳机
- 华硕|双12大促来了!带你种草全新华为“书房三宝”
- 北大|北大天才少年“还俗僧人”柳智宇宣布恋情:出家时就认识她了 女方未提买房买车
- 数学|北大数学天才柳智宇还俗后宣布恋情:出家时就认识她了 符合找女友标准
- 短视频|【海归求职网CareerGlobal】13年500强企业工作经验资深行业顾问带你深入了解产品经理岗位!
- 燃气热水器|双增压零冷水,这冬天云米AI燃气热水器Super带你酣畅淋漓地洗澡
