共计 1190 个字符,预计需要花费 3 分钟才能阅读完成。
快照读
比方咱们新建一个表,而后新建两行数据,当初表的内容是这样的
咱们新建一个事务,称为 Query1。
begin;
select * from test1; ## 第一次查问
select * from test1; ## 第二次查问
commit;
而后执行第一次查问的语句,查问内容跟表内容一样,失常。
而后咱们新建一个事务,执行 update 操作,咱们称为 Query2
begin;
update test1 set `name` = 'yunzhi' where id = 1;
select * from test1;
commit;
执行他 Query2, 不提交,此时查问后果为
而后再执行 Query1 的第二次查问
咱们发现 Query1 的查问和 Query2 的查问的后果是不同的。
这就波及到 mysql 的多版本并发控制技术, 简称 MVCC(Multi-Version Concurrency Control)。
基于上边的例子,咱们能够了解为当开启一个事务的时候,会对事务设置一个版本号,且版本号一一递增,同时对每行数据进行新增,更新,删除也会同步更新版本号同以后事务版本号。当在事务内进行查问操作且不提交的时候,
默认执行快照读操作,快照读只能查问到小于等于以后版本的数据。
让咱们复盘一下方才的操作。
咱们认为新增数据时 version = 1; 所以每行数据版本号为 1。
咱们在新建 Query1 事务的时候,version = 2;
begin; ## version = 2;
select * from test1; ## 第一次查问
select * from test1; ## 第二次查问
commit;
咱们再新建 Query2 事务的时候,version = 3;
begin; ## version = 3;
update test1 set `name` = 'yunzhi' where id = 1;
select * from test1;
commit;
再执行 Query1 的第二次查问时,
因为 Query1 的对应版本号为 2, 无奈查到对应版本号为 3 的 ’yunzhi’ 数据。
快照读解决了不可反复读问题。不可反复读,即前后屡次读取,数据内容不统一
以后读
对于会对数据批改的操作 (update、insert、delete) 都会执行以后读。假如要 update 一个记录,另一个事务曾经 delete 这条数据并且 commit 了,这样就会产生抵触,所以 update 的时候必定要晓得最新的信息。
在执行批改数据的时候,首先会执行以后读,而后把返回的数据加锁,之后执行批改数据。加锁是避免别的事务在这个时候对这条记录做什么,默认加的是排他锁,也就是你读都不能够,这样就能够保证数据不会出错了。
想要手动执行以后读须要在后缀加for update
, 如
select * from test1 for update;
如果一个事务执行以后读操作且不提交,另一个事务是无奈执行以后读操作的。这也阐明了以后读加了锁。
总结
mysql 查问操作默认执行快照读操作,批改数据会执行以后读操作。