数据库事务以及隔离级别

事务的四大特性

  • 原子性
    数据库执行的最小单位,要么都执行,要么都不执行

例:张三给李四转账10元
李四账户增加10元,张三账户减少十元,要么都执行成功,要么都失败(回滚)

  • 隔离性
    两个事务的操作,不能相互影响

例:张三给李四转20元,王五给孙六转10元。
两个事务互不干扰,不能张三的钱转给孙六。

  • 一致性
    事务前后,数据总额一致

例:张三转给李四40元
张三和李四的总账户余额不变。
原子性和隔离性保证一致性

  • 持久性
    事务执行后存入数据库,即写入磁盘,对数据的改变是永久的。

事务的隔离级别

  • (READ UNCOMMITTED)读未提交
    一个事务可以读到其他事务还没有提交的数据,会出现脏读

  • (READ COMMITTED)读已提交
    一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值,会出现不可重复读、幻读

  • (REPEATABLE READ)可重复读
    一个事务第一次读过某条记录后,即使其他事务修改了该记录的值并且提交,该事务之后再读该条记录时,读到的仍是第一次读到的值,而不是每次都读到不同的数据,这就是可重复读,这种隔离级别解决了不可重复,但是
    还是会出现幻读

  • (SERIALIZABLE)串行化
    不允许读-写、写-读的并发操作,可以读-读操作
    因为对同一条记录的操作都是串行的,所以不会出现脏读、不可重复读,幻读等现象。

注意

这四种隔离级别是SQL的标准定义。MYSQL默认级别是repeatable read ,且不会出现幻读

MySQL通过MVCC实现事务控制

在介绍MVCC前,先介绍一下两个概念 版本链和ReadView

版本链

对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列( row_id并不是必要的,我们创建的表中有主键或者非NULL唯一键时都不会包含row_id列):

trx_id:每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列。
roll_pointer:每次对某条记录进行改动时,这个隐藏列会存一个指针,可以通过这个指针找到该记录修改前的信息

ReadView

对于使用READ UNCOMMITTED隔离级别的事务来说,直接读取记录的最新版本就好了,对于使用SERIALIZABLE隔离级别的事务来说,使用加锁的方式来访问记录。对于使用READ COMMITTED和REPEATABLE READ隔离级别的事务来说,就需要用到我们上边所说的版本链了,核心问题就是:需要判断一下版本链中的哪个版本是当前事务可见的。
ReadView中主要包含4个比较重要的内容:

  1. m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。
  2. min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小值。
  3. max_trx_id:表示生成ReadView时系统中应该分配给下一个事务的id值。
  4. creator_trx_id:表示生成该ReadView的事务的事务id。

注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1, 2, 3这三个事务,之
后id为3的事务提交了。那么一个新的读事务在生成ReadView时, m_ids就包括1和2, min_trx_id的值就是1,
max_trx_id的值就是4。

有了这个ReadView,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见:

1)如果被访问版本的trx_id属性值与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自己修改过的记录,所以该版本可以被当前事务访问。
2)如果被访问版本的trx_id属性值小于ReadView中的min_trx_id值,表明生成该版本的事务在当前事务生成ReadView前已经提交,所以该版本可以被当前事务访问。
3)如果被访问版本的trx_id属性值大于ReadView中的max_trx_id值,表明生成该版本的事务在当前事务生成ReadView后才开启,所以该版本不可以被当前事务访问。
4)如果被访问版本的trx_id属性值在ReadView的min_trx_id和max_trx_id之间,那就需要判断一下trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版本可以被访问

什么是MVCC

MVCC(Multi-Version Concurrency Control ,多版本并发控制)指的就是在使用READ COMMITTD、REPEATABLE READ这两种隔离级别的事务在执行普通的SEELCT操作时访问记录的版本链的过程。可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能。READ COMMITTD、REPEATABLE READ这两个隔离级别的一个很大不同就是:生成ReadView的时机不同,READ COMMITTD在每一次进行普通SELECT操作前都会生成一个ReadView,而REPEATABLE READ只在第一次进行普通SELECT操作前生成一个ReadView,之后的查询操作都重复使用这个ReadView就好了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RwTo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值