Mysql的事务

92 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

Mysql的事务

Mysql属于关系型数据库,关系型数据库在处理事务一般要满足ACID的特性;

1、ACID特性
  • 原子性(Atomicity) :简而言之就是操作数据的修改,要么全都执行,要么全都不执行。
  • 一致性(Consistent) :在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规 则都必须应用于事务的修改,以保持数据的完整性。
  • 隔离性(Isolation) :数据库系统提供一定的隔离机制,保证事务在不受外部其他事务的影响。这意味着事务处理过程中的中间状态对外部是不可见的;InnoDB 支持的隔离性有 4 种,隔离性从低到高分别为:读未提交、读提交、可重复读、可串行化。锁 和多版本控制(MVCC)技术就是用于保障隔离性的;
  • 持久性(Durable) :事务完成提交之后,它对于数据的操作是永久性的;
2、并发事务产生的影响以及解决办法
  • 脏读

    一个事务对一条数据做了修改,但是还未交,此时另外一个事务读到了这个还未提交的脏数据,同时依据这个脏数据做了进一步的处理,可能造成数据错乱,称为脏读;

  • 幻读

    同一个事务按照相同的语句查询,但是前后得到的结果不一致,可能就是在后面一次读到了其他事务提交的数据,不符合隔离性的原则;

  • 不可重复读

    事务读取同一个数据前后不一致

  • 更新丢失

    许多事务同一时间更新一行数据,读取到的数据版本是一样的,但是更新有前后,最后更新的事务会把前面更新的都覆盖掉;

解决方案:

  1. 串行化

    让所有事务串行化,同一时间只执行一个事务,不会产生并发冲突,但是效率低下;

  2. 互斥锁

    对于事务要操作的那行数据加锁,先获得所的事务执行,后面的等待;

  3. 读写锁

    读之间相当于共享锁,涉及写的操作还是要互斥;

  4. MVCC

    • 解决了读和读并行,还支持读和写、写和读 的并行,写写还是无法并行的

    • 概念:

      ​ MVCC(Multi Version Concurrency Control)意思多版本控制,是指为了实现在数据库中高并发数据访问,对修改的数据进行多版本并发处理;

      ​ 并通过事务的可见性来保证事务能看到自己应该看到的数据版本, 在每次事务修改操作之前,都会在Undo日志中记录修改之前的数据状态和事务id, 该备份记录可以用于其他事务的读取,也可以进行必要时的数据回滚;

    • 实现原理

      ​ MVCC实现了并发操作读不加锁,读写不冲突。极 大的提升系统的并发性能,因此基本的关系型数据库都使用这种方式,Mysql在读已提交(Read Commited )和可重复读隔离(Repeatable Read)级别下都实现了MVCC机制。对某行数据的读和写两个操作默认是不会通过加互斥锁锁来保证隔离性的;

    • 关于MVCC的并发读操作

      分成快照读(Snapshot Read)和当前读 (Current Read)两类

      快照读:读取数据记录的快照版本,可能会是历史版本,这种读不加锁;

      当前读: 读取的是最新的数据记录,返回的记录会加锁避免其他事务的影响

    • undo log版本链

      当准备修改一条记录时,会把待更新的数据读取到日志,复制一份当前修改了额数据,通过事务id指向当前记录的上个版本的指针的形式;由此形成一整条链表,可以很轻松的找到当前数据的历史事务操作记录;

3、事务的隔离级别
  • 读未提交
    • 意思就是读取到其他事务还未提交的记录,可能会产生幻读,脏读,不可重复读;
  • 读已提交
    • 解决了脏读问题,但是幻读问题还存在;
  • 可重复
    • 解决了不可重复读,脏读,可能出现幻读;
  • 串行化
    • 啥问题没有

哈哈.png

Mysql默认的事务隔离级别是可重复读