如果事务隔离级别是默认的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必须扫描整个表来处理语句 , 表的每一行都会被锁定 , 从而也会阻塞其他用户插入到这个表中 。 所以创建好的索引 , 让查询不会扫描超过需要的行是很重要的 。
- 微信|遇到不认识的字,用微信1秒就能读出来,操作简单,比字典还方便
- 诈骗|女子遇诈骗反赚骗子1千多 认识炒股专家被坑惨:官方提醒不要想暴富
- 黑科技与建筑的无缝结合,带你回溯千年历史
- 微信|带你了解微信新版本的几个实用功能
- 对于知网论文查重系统带你们来深刻探索一下!
- 本文转自:新华网第十届中国(绵阳)科技城国际科技博览会于11月16日至19日在四川绵阳举...|记者带你体验科博会上的“新”“奇”“特”
- 欧盟|苹果手中的“灰色”出货神器,带你了解卡贴机黑解背后的底层逻辑
- 华硕|11月17日登场!一文带你提前看完我10系列亮点,屏幕太绝
- “智慧水电”应用上线啦!一篇文章带你一探究竟…
- 显示器|无愧经典,从不落伍的CD机带你重拾听音的纯粹