事务简单来说:一个SESSION中所进行所有的操作,要么同时完成,要么同时失败。具体来说,事务指的是满足ACID特性的一组操作,可以通过COMMIT提交一个事务,也可以使用ROLLBACK执行回滚。
数据库事务.png


1、ACID

ACID - 数据库事务正确执行的四个基本要素:

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

一个支持事务(Transaction)中的数据库系统,必需要具有这四种特性,否则在事务过程(Transaction processing)中无法保证数据的正确性,交易过程极可能达不到交易。
数据库ACID.png

2、并发一致性问题

并发一致性解决方案:

  • 产生并发一致性问题主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。
  • 并发控制可以通过封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更轻松的方式处理并发一致性问题

在并发环境下,事务的隔离性很难保证,因此会出现很多并发一致性问题。

  • 丢失修改

T1和 T2两个事务都对一个数据进行修改,T1先修改,T2随后修改,T2的修改覆盖了 T1的修改。
数据库并发一致性-丢失修改.png

  • 脏读

T1修改一数据, T2随后读取这个数据。T1撤销了这次修改,那么T2读取的数据是脏数据。
数据库并发一致性-脏数据.png

  • 不可重复读

T2读取一个数据,T1对该数据做了修改,T2再次读取这个数据,此时读取的结果和第一次读取的结果不同。
数据库并发一致性-不可重复读.png

  • 幻读

T1读取某个范围数据,T2在这个范围内插入新数据,T1再次读取这个范围的数据,此时读取的结果和第一次读取的结果不同。
数据库并发一致性-幻读.png

3、事务隔离

数据库隔离级别:

  • 未提交读(READ UNCOMMITTE) - 事务中的修改,即使没有提交,对其他事务也是可见的。
  • 已提交读(READ COMMITTED) - 一个事务只能读取已经提交的事务所做的修改。
  • 重复读(REPEATABLE READ) - 保证在同一个事务中多次读取同样数据的结果是一样的。
  • 串行化(SERIALIXABLE) - 强制事务串行执行。

数据库隔离被解决的问题:

隔离级别 脏读 不可重复读 幻读
未提交读 X X X
已提交读 Y X X
可重复读 Y Y X
串行化 Y Y Y

4、分布式事务
  • 在单一数据节点中,事务仅限于对单一数据库资源的访问控制,称之为本地事务。几乎所有的成熟的关系型数据库都是提供了对本地事务的原生支持。
  • 分布式事务是指事务的参与者,支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

两阶段提交
两阶段提交(XA)对业务侵入很小。它最大的优势就是对使用方透明,用户可以像使用本地事务一样使用基于 XA协议的分布式事务。XA协议能够严格保障事务的ACID特性。

严格保证事务ACID特性是一把双刃剑。事务执行在过程中需要将所需资源全部锁定,它更加适合于执行时间确定的短事务。对于长事务来说,整个事务进行期间对数据的独占,将导致对热点数据依赖的业务系统并发性能衰退明显。因此在高并发的性能至上场景中,基于 XA协议的分布式事务并不是最佳选择。

柔性提交
如果将实现了ACID的事务要素的事务称为刚性事务的话,那么基于 BASE事务要素的事务则称为柔性事务。BASE是基本可用、柔性状态和最终一致性这三要素的缩写。

  • 基本可用(Basically Available)保证分布式事务参与方不一定同时在线。
  • 柔性状态(Soft State)则允许系统状态更新有一定的延时,这个延时对于客户来说不一定能够察觉。
  • 最终一致性(Eventually Consistent)通常通过消息传递的方式保证系统的最终一致性。

ACID事务中对隔离性的要求很高,在事务执行过程中,必须将所有的资源锁定。柔性事务的理念则是通过业务逻辑将互斥锁操作从资源层面上移至业务层面。通过放款对强一致性要求,来换取系统吞吐量的提升。

基于ACID的强一致性事务和基于BASE的最终一致性事务都不是硬谈,只有在最适合的场景中才能发挥它们的最大长处。可以通过下表详细对比它们之间的区别。

事务方案对比


本地事务 两(三)阶段提交 柔性事务
业务改造 实现相关接口
一致性 不支持 支持 最终一致性
隔离性 不支持 支持 业务方保证
并发性能 无影响 严重衰退 略微谁退
适合场景 业务方处理不一致 短事务 & 低并发 长事务 & 高并发