文章目录

  • 1 事务概述
  • 2 并发事务处理带来的问题
  • 2 隔离性概述
  • 3 事务隔离的实现
  • 4 mvcc的由来
  • 4.1 当前读
  • 4.2 快照读
  • 4.3 mvcc
  • 4.3.1 mvcc的实现机制


1 事务概述

事务就是要保证一组数据库操作,要么全部成功,要么全部失败。在mysql中事务支持是在引擎层实现的。(myisam并不支持事务)
一个运行良好的事务必须具备acid

  • 原子性
    一个事务必须被视为不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分
  • 一致性
    数据库总是从一个一致性的状态转换到另外一个一致性状态
    一致性是基础,也是最终目的,其他三个特性(原子性、隔离性和持久性)都是为了保证一致性的
  • 隔离性
    一个事务的执行过程中不能影响到其他事务的执行,即一个事务内部的操作及使用的数据对其他事务是隔离的,并发执行各个事务之间无不干扰。
  • 持久性
    一旦事务提交,则所做的修改就会永久保存到数据库中

2 并发事务处理带来的问题

  • 更新丢失

当两个或多个事务选择同一行,由于每个事务都不知道其他事务的存在,就会发生更新丢失问题–最后的更新覆盖了其他事务所做的更新。(在一个事务未提交前,另个程序员无法访问其文件即可)

  • 脏读

事务a读取到了事务b已修改但尚未提交的数据,还在这个数据做了操作,如果b事务回滚,a读取的数据无效

  • 不可重复读

一个事务按相同的查询条件重新读取以前检索过的数据,发现其读出的数据已经发生改变

  • 幻读

一个事务按相同的查询条件重新读取以前检索过的数据,发现其他事务插入满足其查询条件的新数据

注意:脏读是事务b里面修改了数据,幻读是事务b里面新增了数据

mysql 修改事务隔离级别 mysql事务隔离级别实现_mysql

2 隔离性概述

事务会有ACID特性,即原子性,一致性,隔离性,持久性,当数据库上有多事务同时执行时,就可能出现脏读,不可重复读,幻读的问题,因此有了隔离性,隔离级别越高,效率就越低。隔离事务级别包括:读未提交,读提交,可重复读和串行化

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

在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启东时创建的,整个事务在期间都用这个视图。在“读提交”隔离级别下,这个视图是在每个sql语句开始执行的时候创建的。“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念,而串行化,隔离级别是直接用加锁的方式来避免并行访问。

3 事务隔离的实现

在mysql中,每条记录在更新时会同时记录一条回滚操作,其实就是在行上加上个回滚指针指向undo log存储的以前数据,记录上的最新值,通过会通过回滚操作,得到前一个状态的值。可重复读与读提交可以通过mvcc进行实现,而串行化则直接加锁

mvcc又是借助了undo log 进行了实现

mysql 修改事务隔离级别 mysql事务隔离级别实现_数据库_02

4 mvcc的由来

4.1 当前读

当前读是读取的最新版本,需要保证其他事务本能修改读取记录,会对记录进行加锁

其形式

  • select … lock in share mode (共享读锁)
  • select …for update
  • update,delete,insert

4.2 快照读

单纯的select 操作对读操作不加锁,不包括上述的select…lock in share mode,select… for update

read committed隔离级别:每次select 都生成一个快照读

read repeatable 隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读

快照读的实现方式为**undolog和mvcc **

4.3 mvcc

MVCC(Multi-Version Concurrency Control),即多版本并发控制,数据库通过它能够做到遇到并发读写的时候,在不加锁的前提下实现安全的并发读操作,是一种乐观锁的实现方式,能大大提高数据库的并发性能。指的就是在使用READ COMMITTD、REPEATABLE READ这两种隔离级别的事务在执行普通的SEELCT操作时访问记录的版本链的过程

4.3.1 mvcc的实现机制

innodb会给数据库中的每一行增加三个隐藏字段,trx_id(事务id),roll_ptr(回滚指针),和row_id(隐式主键),每开启一个新事务,事务版本就会递增。

mvcc实现的依赖是undo log和read view

  • undo log 记录是数据表记录行的多个版本,是事务执行过程中的回滚端

在新增或修改的流程中事务会先使用“排他锁”锁定该行,将该行当前的值复制到undo log中,然后再真正地修改当前行的值,最后填写事务的DB_TRX_ID,使用回滚指针DB_ROLL_PTR指向undo log中修改前的行DB_ROW_ID。

mysql 修改事务隔离级别 mysql事务隔离级别实现_mysql_03

  • read view 主要是用来判断版本连中的那个版本是当前事务可见的

Read View就是事务进行快照读操作的时候生产的读视图(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID。

  • min_trx_id:read view 生成是,活跃事务id列表中的最小id
  • max_rtx_id;read view 生成时,当前最大事务的id

mysql 修改事务隔离级别 mysql事务隔离级别实现_mvc_04