1.事务
事务(Transaction),在数据库操作中,指的是一个原子性的操作序列。这个序列中的所有操作要么全部成功,要么全部失败,绝不会出现部分成功的情况。你可以将事务想象成一个数据库操作的“整体”,要么一起完成,要么一起取消。
事务通常由高级数据库操作语言或编程语言书写的用户程序所引起,并用形如 begin transaction
或 end transaction
语句(或函数调用)来界定。事务由事务开始(begin transaction
)和事务结束(end transaction
)之间执行的全体操作组成。
事务通常具备以下四个特性,简称为 ACID:
- 原子性(Atomicity):事务是不可分割的最小操作单位,事务中的所有操作要么全部成功,要么全部失败,不会停留在中间状态。
- 一致性(Consistency):事务完成后,系统状态应该保持一致,即从一个一致的状态转换到另一个一致的状态。
- 隔离性(Isolation):在事务未完成之前,不允许其他事务访问它的数据,保证事务之间相互独立,不受其他事务的干扰。
- 持久性(Durability):一旦事务提交后,所做的更改将永久保存在数据库中,即使系统崩溃也不会丢失事务的结果。
(1)分布式事务
分布式事务:在多个独立的资源或服务之间保证一致性的事务操作。涉及多个系统(如多个数据库、微服务等),并确保所有参与的资源要么全部成功,要么全部失败,以保持数据一致性。分布式事务广泛应用于分布式系统、微服务架构等需要跨数据库或跨服务的场景。
(2)Java 分布式事务
分布式事务:是指在多个数据库或系统中,通过技术手段,协调多个操作,使其作为一个整体来执行。也就是说,这些操作要么全部成功,要么全部失败,以保证整个系统的数据一致性。通常,分布式事务会采用两阶段提交(2PC)等协议,由事务管理器(如Atomikos、Bitronix)来协调各个参与者(如数据库)的行为。事务管理器会向所有参与者发送提交或回滚的请求,只有所有参与者都确认收到并执行了请求,事务才算完成。
通过 技术实现的分布式事务控制,通常使用 () 进行管理。 允许 应用程序在多个不同的数据源之间管理全局事务,确保在分布式系统中保持数据一致性。 分布式事务通常使用事务管理器(如 Atomikos、Bitronix)协调多个资源,并通过协议(如 2PC)实现事务的提交或回滚。
(3)2PC(Two-Phase Commit)
2PC 协议简单、实现容易,但在网络不稳定的环境下,可能出现阻塞问题。例如,如果协调者在提交阶段宕机,所有参与者将被阻塞在等待状态,影响系统性能。此外,2PC缺少有效的容错机制,一旦协调者出现故障,事务状态可能难以恢复。
TCC(Try-Confirm-Cancel)
- Try 阶段:资源预留。
- Confirm 阶段:确认提交。
- Cancel 阶段:取消操作。
TCC 具备灵活的错误处理和恢复机制,适用于异步、长事务和高并发场景。每个服务都可以实现自己的 Try、Confirm、Cancel 逻辑,从而避免传统 2PC 带来的阻塞和性能问题,但实现难度相对较高,因为需要开发人员手动编写事务的补偿逻辑。
CAP 理论:CAP 理论由计算机科学家 Eric Brewer 在 2000 年提出,后来被广泛接受并成为分布式系统设计中的重要指导原则。分布式系统中的基本定理,指出在一个分布式数据存储系统中,无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)这三个特性。
BASE 理论:一种相对 CAP 理论的分布式系统设计理论,提出一种弱一致性的替代方案,用于满足分布式系统的高可用性需求。核心思想是弱化强一致性的要求,以提高系统的可用性和性能。BASE 适用于那些不需要强一致性、但需要高响应速度和高可用性的分布式系统,比如电商平台和社交媒体等。
XA
XA是一种两阶段提交协议规范,由X/Open组织提出。它定义了资源管理器(如数据库)和事务管理器之间交互的接口,用于协调分布式事务。
- XA的两个阶段:
a.准备阶段(Prepare):事务管理器向所有参与者发送准备提交的请求。如果所有参与者都准备好了,则进入提交阶段;否则,进入回滚阶段。
b.提交(或回滚)阶段:事务管理器向所有参与者发送提交或回滚的请求。所有参与者根据收到的指令执行提交或回滚操作。
- XA的优点:
a.实现了强一致性,保证了数据的一致性。
- XA的缺点:
a.性能问题:2PC协议涉及到多个网络交互,性能较低。
b.单点故障:事务管理器是单点,一旦故障,整个系统可能无法正常工作。
c.阻塞问题:参与者在准备阶段需要一直持有锁,影响系统的并发性能。
AT(补偿事务)
AT是一种基于补偿的分布式事务解决方案。它在业务操作之前,会先记录操作的补偿逻辑,如果业务操作失败,则执行补偿逻辑来撤销之前的操作。
- AT的三个阶段:
a.Try阶段:执行业务操作,并记录补偿信息。
b.Confirm阶段:如果Try阶段成功,则提交事务。
c.Cancel阶段:如果Try阶段失败,或者Confirm阶段失败,则执行补偿操作。
- AT的优点:
a.性能较好:避免了长时间的锁等待。
b.灵活度高:可以自定义补偿逻辑。
- AT的缺点:
a.实现复杂:需要开发人员手动编写补偿逻辑。
b.补偿逻辑的正确性:补偿逻辑的编写难度较大,如果编写不当,可能导致数据不一致。
SAGA
SAGA是一种长事务解决方案,它将长事务拆分成多个本地事务,通过补偿机制来保证最终一致性。
- SAGA的执行过程:
a.正向操作:按照顺序执行一系列本地事务。
b.补偿操作:如果某个本地事务执行失败,则按照逆序执行相应的补偿事务。
- SAGA的优点:
a.灵活度高:可以根据业务需求灵活调整。
b.性能较好:避免了长事务带来的性能问题。
- SAGA的缺点:
a.实现复杂:需要仔细设计补偿逻辑,保证最终一致性。
b.错误处理复杂:需要考虑各种异常情况,并保证补偿操作的幂等性。
2.Seata
https://seata.apache.org/zh-cn/
是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
(1)AT 模式
一阶段 - 执行业务操作并记录回滚日志: 会在多个服务中执行业务操作并记录回滚日志。
二阶段 - 根据事务协调器的指令提交或回滚: 的事务协调器会决定最终是提交还是回滚整个分布式事务。
写隔离
例:两个并发的分布式事务 T1 和 T2,初始值为 1000, 通过本地锁和全局锁的组合确保数据的一致性和隔离性。
读隔离
在 的 AT 模式中,默认的全局读隔离级别是读未提交(Read Uncommitted),这意味着事务在读取数据时可能会读到尚未提交的变更数据。这是为了提升性能,因为读未提交可以减少锁的竞争。但在某些场景中,系统可能需要更高的隔离级别,即 读已提交(Read Committed),这可以通过在查询时使用 SELECT FOR UPDATE 语句来实现。
3.案例
https://github.com/apache/incubator-seata-samples
用户购买商品的业务逻辑。
整个业务逻辑由 3 个微服务提供支持
- 仓储服务(stock service):对给定的商品扣除仓储数量。
- 订单服务(order service):根据采购需求创建订单。
- 帐户服务(account service):从用户账户中扣除余额。
图片
(1)数据库
创建 MySQL 数据库:
依次创建 stock、order 和 account 数据库:
(2)数据表
依次在 stock、order 和 account 数据库创建 stock_tbl、order_tbl 和 account_tbl 数据表,每个数据库附带 undo_log 数据表:
(3)启动服务
https://github.com/apache/incubator-seata/releases
选择下载的是:https://github.com/apache/incubator-seata/releases/download/v1.5.2/seata-server-1.5.2.zip
解压之后,进入 seata-server-1.5.2/seata/bin 目录,执行:
查看日志:
(4)运行示例
依次启动:
- DubboStockServiceStarter:初始化库存数据(添加库存记录)。
- DubboAccountServiceStarter:初始化账户数据(添加用户账户记录)。
- DubboOrderServiceStarter:启动订单服务(等待下单操作)。
- DubboBusinessTester:执行测试场景(下单操作,触发分布式事务)。
启动账户服务。
初始化账户表数据:
- 删除用户 U100001 的账户记录(若存在)。
- 插入一条新记录,给用户 U100001 分配初始余额 999。
启动订单服务。
订单服务启动后,等待买家下单。
启动库存服务。
初始化库存表数据:
a.删除商品 C00321 的库存记录(若存在)。
b.为商品 C00321 添加库存 100。
测试整个电商平台。
模拟业务场景:用户 U100001 购买商品 C00321,数量为 2。
正常事务
选择注释 dubbo/src/main/java/io/seata/samples/dubbo/service/impl/BusinessServiceImpl.java
异常事务
选择保留 dubbo/src/main/java/io/seata/samples/dubbo/service/impl/BusinessServiceImpl.java
图片