浅谈事务的四个基本特性

浅谈事务的四个基本特性

基本概念

我们都知道事务的四个基本特性:原子性(A)、一致性(C)、隔离性(I)、持久性(D)

  • 原子性:事务必须是一个原子的操作序列单元,一次执行过程中要么全部成功,要么全部失败
  • 一致性:事务的执行不能破坏数据的完整性和一致性,事务执行前后,数据都处于一致性状态
  • 隔离性:在并发环境中,事务之间互相隔离、互不影响,不同事务操作相同的数据时,都保持各自完整的数据空间【具体看隔离级别】,互不影响。
  • 持久性:事务一旦提交之后,数据必须被持久的保存到磁盘中,不会存在事务已提交,数据却没落库的情况。

MySQL对于四种特性的实现方式

我们都知道mysql数据库只有innodb引擎支持事务,那么这四种特性分别是如何实现的呢:

  1. 原子性:innodb引擎通过支持事务回滚的方式保证原子性,我们都知道用户创建的表都会有几个隐藏字段:当前事务id、rowId、上一个版本的回滚指针,其中回滚指针就记录了本行数据在undolog中的行数据历史版本的地址,方便在事务执行失败的时候回滚数据:比如执行了insert语句,那回滚的时候就执行delete操作;执行了delete语句,那回滚的时候就执行insert操作;执行了某些字段的update操作,那回滚的时候就执行这些字段的回滚update操作。这里需要注意undolog只有在事务回滚的时候才有用,因此在事务成功提交后,这个事务相关的undolog就会删除。undulog会形成事务的历史版本数据的链表,头结点是最新版本的数据。
  2. 隔离性:ps我们都知道读未提交、读已提交、可重复度和串行化四种隔离级别,其中读已提交解决脏读问题,可重复度解决不可重复读的问题,串行化解决幻读的问题。在innodb引擎中,具体通过锁和mvcc(多版本并发控制)来保证事务的隔离性。而讨论隔离性需要在事务并发的场景来看,那事务之间无非就三种竞争场景:读读竞争(不会造成数据安全问题)、读写竞争(通过mvcc实现)、写写竞争(通过加锁的方式实现)。
    这里需要回顾下mvcc:mvcc主要由三部分实现:隐藏字段(已介绍)、undolog(已介绍)、读视图(readview)。读视图是在事务进行快照度的时候产生的,并不能存储实际的数据,而是记录当前活跃的事务id,读视图通过一个可见性算法来判定不同的隔离级别下事务能够读到什么版本的数据。读视图有三个属性值:trx_list(读视图生成时的活跃事务id)、up_limit_id(当前活跃列表中最小的事务id)、low_limit_id(即将分配的下一个事务id),不同隔离级别下,会根据可见性算法来判定某个事务是否能够快照读某行数据,会根据这行数据的DB_trx_id去和读视图的三个属性比较。这里需要强调的是隔离级别RC每次快照读都会创建新的读视图,而RR每次快照读都使用第一次的读视图,这也解释RR为什么可以解决可重复度的问题。
  3. 持久性:innodb引擎通过redolog保证数据能够溢写到磁盘,redolog基于预写日志(WAL:write-ahead-log)机制,注意为了保证读写性能是顺序记录的,就像一个账本一样把所有事务的记录记下来,所以磁盘溢写失败后,可以通过redolog来保证将写失败的数据在磁盘上恢复。redolog中的二阶段提交:在innodb中,既有redolog又有binlog,那如何保证两个日志都写成功了呢,即通过二阶段提交方式,mysql会通过缓存机制先从内存中读数据,如果内存不存在就先从磁盘读到内存,数据更新的时候,先更新内存,然后开始写redolog,这时redolog处于prepare状态,再开始写binlog,最后事务提交,此时处于commit状态,完成两个日志的双写。换句话说,只有两个日志都写成功了,数据才会最终溢写到磁盘,否则就会写失败。
  4. 一致性:由以上三种特性共同来保证的。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值