传统事务
事务是原子的,要么都成功要么都失败。
再进一步看就有ACID这四个属性,原子性(Atomictiy)、一致性(Consistency)、隔离性(Isolation)、持久性(Durabilit)。
- 原子性: 事务的最小单元, 在一个事务里面,要么全部成功,要么全部回滚,部分完成不是一个事务的概念。
- 一致性:在事务开始和完成的时候,数据和资源将遵循业务规则的一致性,没有被破坏的状态。
- 隔离性:每个事务应该与其他事务隔离,避免数据破坏。一个事务,直到它被成功提交之后,它的结果对于任何其他的事务才是可见的。
- 持久性:一个已提交事务的任何结果都必须是永久性的,即“在任何系统崩溃的情况下都能保存下来”。通常,事务的结果被写入持续性存储。
柔性事务
在电商领域等互联网场景下,传统的事务在数据库性能和处理能力上都暴露出了瓶颈。在分布式领域基于CAP理论以及BASE理论,有人就提出了 柔性事务 的概念。CAP(一致性、可用性、分区容忍性)理论大家都理解很多次了,这里不再叙述。说一下BASE理论,它是在CAP理论的基础之上的延伸。包括 基本可用(Basically Available)、柔性状态(Soft State)、最终一致性(Eventual Consistency)。
- 基本可用 : 分布式系统出现故障的时候,允许损失一部分可用性。比如,京东618大促的时候,对一些非核心链路的功能进行降级处理。核心高可用,非核心可降级。
- 柔性状态: 允许系统存在中间状态,这个中间状态又不会影响系统整体可用性。比如,数据库读写分离,写库同步到读库(主库同步到从库)会有一个延时,这样实际是一种柔性状态。
- 最终一致性: 数据库主从复制的例子,经过数据同步延时之后,最终数据能达到一致。
参考: https://www.jianshu.com/p/ab1a1c6b08a1
区别
- ACID是传统数据库常用的设计思想,它追求的是强一致性。
- BASE是大型分布式系统场景下的设计思想,通过牺牲强一致性获得高可用性。
柔性事务针对分布式事务的解决方法:
1、记录日志+补偿
记录事务的开始和结束状态。事务根据日志记录找回事务的当前执行状态,并根据状态决定重试异常步骤,也就是正向补偿,或者回滚上一次执行步骤,也就是反向补偿。
2、消息
多次重试,也就是发送多次消息,由于要多次重发,所以程序必须是幂等(同一操作反复执行多次结果不变),这是非常具有互联网特征的一种模式。
3、“无锁”设计
放弃锁是一个解决问题的思路。比如通过乐观锁,大多数是基于版本号来实现。
update goods
set name=#{name},
remaining_number=#{remainingNumber},
version=version+1
where id=#{id} and version=#{version}
柔性事务的实现需要有下面2点作为保证:
1、应用程序一定要做幂等实现,特别是对数据库进行数据修改操作的时候。
2、远程模块之间采用异步消息驱动,异步消息还可以起到检查点的作用。