Mysql-事务

事务

事务是什么?

在知道事务的相关信息之前,我们需要先理解:什么是事务?

事务是一组不可再分的最小的执行单元,即事务内的数据,必须要么全部执行完成,要么不执行,即可为不可再分。

Mysql中只有支持事务的存储引擎,才可以使用事务,例如InnoDB。

事务的四个特性


原子性

事务的原子性要求事务内的一组操作是原子操作,不可中断的,如果发生了中断,则所有的修改都会被回滚。即只有所有的操作都是成功的,这个事务才会成功。

例如一个转账的操作,分为了两个部分:从A账户扣除金额,B账户加上相应的金额。只有两个部分的操作都成功,则整个事务才算成功,转账操作才算完成。如果第一部分成功,第二部分失败,则整个事务会失败,A账户的金额也不会减少,B账户的金额也不会增多。

一致性

一致性是指:在执行事务的前后,数据库是从一个一致性状态,转移到另一个一致性状态。即数据库的一致性,不会因为事务的执行而破坏。

例如转账,假如转账前,A和B的账户总额是100元,转账后A和B的账户总额也应该是100元,不会增多,也不会减少。

隔离性

隔离性是指在多个事务并行执行的时候,多个事务之间不会相互影响,即A事务的操作,对与B事务的操作是透明的。

例如转账的时候,如果有A账户向B账户转账,则不能影响C账户向A账户转账。

持久性

持久性是指在事务的执行后的操作结果,对与后续的操作都是可见的,并不会随着服务器的重启,而导致数据不可见。

事务的实现

原子性

事务的原子性由redo log 实现。在提交事务的时候,会使用到两阶段提交的方式提交数据,如果在提交的过程中,服务器发生了意外的宕机,当服务器启动的时候,会通过 redo log 去恢复内存中的数据,如果发现redo log中的数据并未完全提交,会直接回滚之前的操作。

一致性

Mysql会使用 undo log 来保证数据的一致性状态。如果事务在执行过程中失败,或发生未知错误的时候,会使用 undo log 回滚之前的操作。在事务隔离级别中,也会使用 undo log 去实现Mysql的MVCC机制,实现可重复读事务隔离级别。

隔离性

隔离性的保证是使用锁的机制实现,如果多个事务之间在修改同一条数据的时候,会使用锁和MVCC的方式,保证当前事务修改的数据,对其他事务没有影响。

例如如果一个事务在读取的一个数据,正在被其他事务删除或者修改,则Mysql不会等待锁的释放,而是会去读取他的快照版本,来获取数据。

持久性

持久性的实现也会使用 redo log,Mysql修改数据的时候,并不会立马直接将修改的数据落盘,而是通过写 redo log 的方式,先保证数据的修改在redo log 中存在,然后会有后台线程在适当的时候,将内存中修改的数据落盘。

为什么需要事务?

在一组操作中,如果需要一组操作要么同时成功,要么同时失败的时候,就需要使用事务。例如转账过程,如果从A中扣除了金额,但是在B中加上金额之前,服务器意外宕机,导致操作中断,如果此时未使用事务,就会导致A账户的钱少了,但是B账户的钱并未增多,出现错误。

使用事务的时候,可以借助事务的四个特性,保证数据的一致性和完整性,避免脏数据的产生。

事务的隔离级别

并发事务带来的问题

数据更新丢失:如果两个事务之间,互相无感知或者互相不知道对方的存在,就会导致第二个事务在更新的时候,会覆盖掉第一个事务更新的数据,导致数据丢失。

脏读:脏读是指事务在第二次读取到的数据和第一次读取到的数据不一致。因为读取的事务是未提交的事务,所以事务如果回滚,就会导致第二次读取的数据和第一次读取的数据不一样,就产生的脏读的现象。

不可重复读:不可重复读是事务在查询的两次查询中,两次查询的结果不一致。例如,如果A事务在第一次读取数据的时候,读取的是正常的数据,如果此时B事务去修改了他,A事务查出来的数据是B事务修改后的指,导致两次查询的数据不一致。

幻读:幻读是指一开始A事务去查询数据的时候,无法查询到,但是在A事务第二次查询数据的时候,由于其他事务插入了一个新的数据,A事务又可以查询到数据,产生幻读。

  • 读未提交

读未提交是指,一个事务可以读取另一个没有提交的事务中修改的数据。例如,A事务可以读取B事务中修改的数据,但是此时事务B还未提交。

因为B事务还未提交,所以就会导致脏读、幻读和不可重复读。

  • 读已提交

读已提交是指一个事务只能读取其他事务已经提交的数据,对于未提交的数据,不会查询到,可以解决脏读的情况,但是会产生不可重复读和幻读的情况。

  • 可重复读

可重复读:可重复读也只能读取已经提交的数据,对于未提交的数据无法读取。然后借助了MVCC机制,增加了版本链和修改了ReadView的创建时期,解决了不可重复读的情况,具体参考MVCC机制。

  • 串行化

要求最高的一个事务隔离级别,要求所有的事务必须串行化执行,因此并发效率特别低。

事务的分类

扁平事务

扁平事务是最简单的一种事务,他的所有的操作都是在一个层面,其由 begin work开始,由rollback 或者是commit结束。因此其间的操作都是要么都完成,要么都不会完成。

带保存点的扁平事务

带保存点的扁平事务是指,在扁平事务的基础上,增加了保存点的概念。如果一个事务的执行数据比较多,当执行到某一部分,发生错误的时候,如果此时全部回滚,产生的代价比较高,并且局部回滚是可以接收的情况下,可以使用保存点的概念。可以将执行会滚到之前设置的任意一个保存点的位置,则回滚保存点的位置和回滚命令之间的操作都会回滚,其他的操作不会有影响。最终提交的时候,只会提交未回滚的操作。

链事务

链事务更像是带有保存点的扁平事务的一个变种。当带保存点的扁平事务在执行的时候,如果系统崩溃,则所有的保存点都会消失,事务需要重新执行。链事务更像是把保存点当做是一个链接的位置,当上一个事务提交的时候,会把一些必要的数据,传递给下一个事务,并且上一个事务的结束和下一个事务的开始将会原子性的执行,更像是在同一个事务中一样。链事务的方式如下图所示

754297-20160204112125600-267403241.jpeg

嵌套事务

嵌套事务是指一个事务中,可以包含子事务,子事务还可以继续包含子事务,形成一个事务树。当子事务回滚的时候,只会回滚子事务中的操作。当父事务回滚的时候,会回滚该父事务,和父事务下的子事务。子事务提交的时候不会真正的提交,只有在父事务提交的时候,才会一起提交。

分布式事务

分布式事务通常情况下是在分布式环境中运行的扁平事务。在分布式环境下,对与数据的操作可能分布在不同的节点上,如果此时事务需要回滚的时候,需要两个节点的数据同时进行回滚操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值