美文网首页
mysql实战(八)事务的隔离

mysql实战(八)事务的隔离

作者: WAHAHA402 | 来源:发表于2020-12-15 23:20 被阅读0次

    我们知道SQL标准的事务隔离级别包括:读未提交(read uncommitted)、读提交(read committed)、可重复读(repeatable read)、串行化(serializable)。

    简述下四个级别的含义:

    • 读未提交:一个事务还没提交时,它做的变更就能被别的事务看到。
    • 读提交(RC): 一个事务提交之后,它做的变更才会被其他事务看到。
    • 可重复读(RR): 一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的。当然在可重复读隔离级别下,未提交变更对其他事务也是不可见的。
    • 串行化:对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行。

    数据库的多版本并发控制(即常说的MVCC):
    同一条记录在数据库系统中存在多个版本。

    InnoDB中每个事务都有一个唯一的事务ID,叫作transaction id。它是在事务开始的时候向InnoDB事务系统申请的,且严格按照申请顺序递增。因为每个事务的id是有大小顺序的。可重复读(RR)隔离级别下,会对当下的数据产生一个快照,这个快照保证了RR的特性。但是这个快照并不是真的把所有库的数据都拷贝了一份,而是根据有着大小之分的transaction id来确定每行数据的哪个版本在当前事务可见。若该行数据的某个版本的transaction id比当前事务的transaction id小且该版本已提交,则可见;反之不可见。

    行状态变更图

    看到上图,该行数据有四个版本,分别是V1,V2,V3,V4(当前最新版本是V4,前三个值不是真实存在的,而是通过回滚日志undo log根据需要随时可以通过计算获取到的虚拟存在)。此时k的最新值为22,若一个事务trx_id等于18,那么对这个事务来说,该行数据的k值就是11,保证了RR级别下的一致性读。

    这里特别提醒,虽然上述例子中,trx_id等于18的事务获取到的k值是11,但若是trx_id等于25的事务对k值先进行了更新,假如设置k=100,如果trx_id等于18的事务中要更新k值,那么一定是在k=100的基础上更新。

    更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read)。

    且由于行锁的存在,trx_id等于18的事务会被堵住,等待trx_id等于25的事务提交后才能更新。

    相关文章

      网友评论

          本文标题:mysql实战(八)事务的隔离

          本文链接:https://www.haomeiwen.com/subject/knkbgktx.html