分布式事务

区别于本地事务,事务在分布式情况下很重要

本地事务

ACID 基本性质

名称解释
Atomicity原子性要么都执行,要么都回滚
Consistency一致性保证数据的状态操作前和操作后保持一致
Lsolation隔离性多个事务同时操作相同数据库的同一个数据时,一个事务的执行不受另外一个事务的干扰
Durability持久性一个事务一旦提交,则数据将持久化到本地,除非其他事务对其进行修改

隔离级别

脏读不可重复读幻读ORACLE 支持MYSQL 支持

| Y:可以解决
N:不能解决 | 一个事务读取到另外一个事务未提交的数据 | 同一个事务中,多次读取到的数据不一致 | 一个事务读取数据时,另外一个事务进行更新,导致第一个事务读取到了没有更新的数据 | | |
| READ_UNCOMMITTED | Y | Y | Y | Y | Y |
| READ_COMMITTED
(Oracle SQL 默认) | N | Y | Y | N | Y |
| REPEATABLE_READ
(MySQL 默认) | N | N | Y | N | Y |
| SERIALIZABLE | N | N | N | Y | Y |

传播行为

SpringBoot 本地事务失效问题

同一个方法内事务方法互相调用失效

原因:绕过了代理对象

  • 解决办法:使用代理对象调用事务方法
1
2
3
4
5
6
7
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

@EnableAspectJAutoProxy
//开启aspectj动态代理,即使没有接口也能代理,所有代理都由aspectj代理

本地事务在分布式下的问题

例子:在购物订单一块时,需要查询优惠券、库存、积分等多个信息,这几个信息一般由不同微服务负责。下单时各个微服务进行数据库操作,只能保证自己的事务,不能保证其他服务的回滚

分布式事务

CAP 定理与 BASE 理论

CAP 定理

CAP 定理是由加州大学伯克利分校 Eric Brewer 教授提出来的,他指出 WEB 服务无法同时满足一下 3 个属性:

  • 一致性(Consistency) : 客户端知道一系列的操作都会同时发生(生效)
  • 可用性(Availability) : 每个操作都必须以可预期的响应结束
  • 分区容错性(Partition tolerance) : 即使出现单个组件无法可用,操作依然可以完成

在任何数据库设计中,一个 Web 应用至多只能同时支持 CP 或者 AP。显然,任何横向扩展策略都要依赖于数据分区。因此,设计人员必须在一致性与可用性之间做出选择。

面临的问题

BASE 理论

BASE:全称:Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)三个短语的缩写,来自 ebay 的架构师提出。

Base 理论是对 CAP 中一致性和可用性权衡的结果,其来源于对大型互联网分布式实践的总结,是基于 CAP 定理逐步演化而来的。其核心思想是:

既是无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

Basically Available(基本可用)

什么是基本可用呢?假设系统,出现了不可预知的故障,但还是能用,相比较正常的系统而言:

  1. 响应时间上的损失:正常情况下的搜索引擎 0.5 秒即返回给用户结果,而基本可用的搜索引擎可以在 1 秒作用返回结果。
  2. 功能上的损失:在一个电商网站上,正常情况下,用户可以顺利完成每一笔订单,但是到了大促期间,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。

Soft state(软状态)

什么是软状态呢?相对于原子性而言,要求多个节点的数据副本都是一致的,这是一种 “硬状态”。

软状态指的是:允许系统中的数据存在中间状态,并认为该状态不影响系统的整体可用性,即允许系统在多个不同节点的数据副本存在数据延时。

Eventually consistent(最终一致性)

这个比较好理解了哈。

上面说软状态,然后不可能一直是软状态,必须有个时间期限。在期限过后,应当保证所有副本保持数据一致性。从而达到数据的最终一致性。这个时间期限取决于网络延时,系统负载,数据复制方案设计等等因素。

稍微官方一点的说法就是:

系统能够保证在没有其他新的更新操作的情况下,数据最终一定能够达到一致的状态,因此所有客户端对系统的数据访问最终都能够获取到最新的值。

而在实际工程实践中,最终一致性分为 5 种:

1. 因果一致性(Causal consistency)

指的是:如果节点 A 在更新完某个数据后通知了节点 B,那么节点 B 之后对该数据的访问和修改都是基于 A 更新后的值。于此同时,和节点 A 无因果关系的节点 C 的数据访问则没有这样的限制。

2. 读己之所写(Read your writes)

这种就很简单了,节点 A 更新一个数据后,它自身总是能访问到自身更新过的最新值,而不会看到旧值。其实也算一种因果一致性。

3. 会话一致性(Session consistency)

会话一致性将对系统数据的访问过程框定在了一个会话当中:系统能保证在同一个有效的会话中实现 “读己之所写” 的一致性,也就是说,执行更新操作之后,客户端能够在同一个会话中始终读取到该数据项的最新值。

4. 单调读一致性(Monotonic read consistency)

单调读一致性是指如果一个节点从系统中读取出一个数据项的某个值后,那么系统对于该节点后续的任何数据访问都不应该返回更旧的值。

5. 单调写一致性(Monotonic write consistency)

指一个系统要能够保证来自同一个节点的写操作被顺序的执行。

然而,在实际的实践中,这 5 种系统往往会结合使用,以构建一个具有最终一致性的分布式系统。实际上,不只是分布式系统使用最终一致性,关系型数据库在某个功能上,也是使用最终一致性的,比如备份,数据库的复制过程是需要时间的,这个复制过程中,业务读取到的值就是旧的。当然,最终还是达成了数据一致性。这也算是一个最终一致性的经典案例。

5. 总结

总的来说,BASE 理论面向的是大型高可用可扩展的分布式系统,和传统事务的 ACID 是相反的,它完全不同于 ACID 的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间是不一致的。

一致性

问题起源

在电商等业务中,系统一般由多个独立的服务组成,如何解决分布式调用时候数据的一致性?

具体业务场景如下,比如一个业务操作,如果同时调用服务 A、B、C,需要满足要么同时成功;要么同时失败。A、B、C 可能是多个不同部门开发、部署在不同服务器上的远程服务。

在分布式系统来说,如果不想牺牲一致性,CAP 理论告诉我们只能放弃可用性,这显然不能接受。为了便于讨论问题,先简单介绍下数据一致性的基础理论。

强一致

当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性。

弱一致性

系统并不保证后续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

最终一致性

弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。

分布式事务几种方案

SEATA

官方文档:http://seata.io/zh-cn/docs/overview/what-is-seata.html


分布式事务
https://polarisink.github.io/20220813/yuque/分布式事务/
作者
Areis
发布于
2022年8月13日
许可协议