mysql探究-事务的隔离性

事务的特性

ACID

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

今天主要了解的是隔离性。

事务的隔离性

先了解下脏读,不可重复读取,幻读的概念:

  • 脏读:能读到其他事务未提交的数据。

  • 不可重复读:两个事务,事务A先读了某个字段值,事务B把这个字段值改了并提交,事务A再次读时,值已经变了。

  • 幻读:两个事务,事务A首先根据条件索引得到N条数据,然后事务B改变了这N条数据之外的M条或者增添了M条符合事务A搜索条件的数据,导致事务A再次搜索发现有N+M条数据了,就产生了幻读。

事务的隔离性从弱到强的顺序:

  • 读未提交:一个事务还未提交,它所做的变更就可以被别的事务看到,容易出现脏读,幻读,不可重复读取。
  • 读提交:一个事务提交之后,它所做的变更才可以被别的事务看到,会出现幻读,不可重复读取。
  • 可重复读:一个事务执行过程中看到的数据是一致的。未提交的更改对其他事务是不可见的。还是会出现“幻读”。
  • 串行化:对应一个记录会加读写锁,出现冲突的时候,后访问的事务必须等前一个事务执行完成才能继续执行。

读提交和可重复读比较难理解。我们来看下两个并行事务。

事务A事务B
启动事务,查询到字段a的值为1启动事务
查询到字段a的值为1,将1改为2
再次查询到字段a的值为v1
提交事务
再次查询到字段a的值为v2
提交事务
再次查询到字段a的值为v3

如果是读提交, 那么v1为1,v2为2,v3为2。
如果是可重复读, 那么v1为1,v2为1,v3为2。

查看和修改事务隔离性

查看当前事务隔离性:

show variables like 'transaction_isolation';

修改事务隔离性:
通过transaction-isolation命令。

隔离性的实现

以可重复读为例。

首先通过事务更改数据时,每次操作都会记录一个回滚日志(undo log)

那么之前讲隔离性时,根据不同隔离级别, 可能会展示不同的结果,又是怎么做到的?
每个事务操作,都会产生一个read-view(视图),保存下当时的活跃事务ID等信息。当我们通过事务查询时,也会携带当前事务ID等信息。 通过事务ID依据我们定义的隔离级别进行对比,得到需要展示的值。

事务ID是具有自增性的。

同样,数据库每一行数据也有版本。通过更改操作后,版本信息里也保存了最后一次的事务ID。

具体扩展知识:
自行查找Mysql的多版本并发控制(MVCC)。

read-view和回滚日志何时会删除?当系统里么有比这个回滚日志更早的read-view的时候。

通过例子会更好理解:
例子1:
假设某字段所在行的版本中,最后的事务ID为99。

事务A事务B
启动事务(事务ID为100)启动事务(事务ID为101,产生read-viewA,里面存了100,101),将字段a的值1改为2(会生成一条从2改为1的回滚日志)
查询字段a的值(此时会携带当前事务ID为100,与当前行的版本里的事务ID做比较,发现100<101,根据我们定义的可重复读级别,不可见),得到的还是1
提交事务
再次读取,同理,读取到的还是1
提交事务,此时事务B的回滚日志和read-viewA才会删除(所以我们尽量不要使用长事务,会造成大量回滚日志和read-view)

总结三种情况:

  1. 版本未提交,不可见;
  2. 版本已提交,但是是在视图创建后提交的,不可见;
  3. 版本已提交,而且是在视图创建前提交的,可见。

例子2:
当有单独update时的情况:
假设某字段所在行的版本中,最后的事务ID为99。

事务A正常C
启动事务(事务ID为100)
直接执行update,将字段a的值1改为2,此时行版本的事务ID已变成101
进行字段值+1操作,(注意:此时会生成一条从3改为2的回滚日志,产生read-viewA,里面存了100)
读取字段a,值为3
提交事务(清除所有回滚日志和read-view)

这里就很奇怪,照理应该还是在1基础上+1,为什么能感知到字段值已经是2了呢?
因为更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”(current read)。所以读取逻辑和更新时的读取逻辑还是不一样的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值