前言
最近因为工作需要,研究学习了Seata分布式事务框架,本文把自己学习的知识记录一下
Seata总览
cloc代码统计
先看一下seata项目cloc代码统计(截止到2020-07-20)
Java代码行数大约是 97K
代码质量
单元测试覆盖率50%
Demo代码
本文讲的Demo代码是seata-samples项目下的seata-samples-dubbo模块,地址如下:
https://github.com/apache/incubator-seata-samples/tree/master/dubbo
解决的核心问题
AT模式的Demo例子给出了一个典型的分布式事务场景:
- 在一个采购交易中,需要:
- 扣减商品库存
- 扣减用户账号余额
- 生成采购订单
- 很明显,以上3个步骤必须:要么全部成功,要么全部失败,否则系统的数据会错乱
- 而现在流行的微服务架构,一般来说,库存,账号余额,订单是3个独立的系统
- 每个微服务有自己的数据库,相互独立
这里就是分布式事务的场景。
解决方案
AT模式解决这个问题的思路其实很简单,一句话概括就是:
在分布式事务过程中,记录待修改的数据修改前和修改后的值到undo_log表,万一交易中出现异常,通过这个里的数据做回滚
当然,具体代码实现起来,我相信很多细节远没这么简单。
Demo代码结构
从github上clone最新的代码
git clone git@github.com:apache/incubator-seata-samples.git
阅读Demo代码结构
$ cd seata-samples/dubbo/
$ tree -C -I 'target' .
.
├── README.md
├── pom.xml
├── seata-samples-dubbo.iml
└── src
└── main
├── java
│ └── io
│ └── seata
│ └── samples
│ └── dubbo
│ ├── ApplicationKeeper.java
│ ├── Order.java
│ ├── service
│ │ ├── AccountService.java
│ │ ├── BusinessService.java
│ │ ├── OrderService.java
│ │ ├── StorageService.java
│ │ └── impl
│ │ ├── AccountServiceImpl.java
│ │ ├── BusinessServiceImpl.java
│ │ ├── OrderServiceImpl.java
│ │ └── StorageServiceImpl.java
│ └── starter
│ ├── DubboAccountServiceStarter.java
│ ├── DubboBusinessTester.java
│ ├── DubboOrderServiceStarter.java
│ └── DubboStorageServiceStarter.java
└── resources
├── file.conf
├── jdbc.properties
├── log4j.properties
├── registry.conf
├── spring
│ ├── dubbo-account-service.xml
│ ├── dubbo-business.xml
│ ├── dubbo-order-service.xml
│ └── dubbo-storage-service.xml
└── sql
├── dubbo_biz.sql
└── undo_log.sql
13 directories, 27 files
-
在io.seata.samples.dubbo.starter包下的4个*Starter类,分别模拟上面所述的4个微服务
- Account
- Business
- Order
- Storage
-
4个服务都是标准的dubbo服务,配置文件在seata-samples/dubbo/src/main/resources/spring目录下
-
运行demo需要把这4个服务都启动起来,Business最后启动
-
主要的逻辑在io.seata.samples.dubbo.service,4个实现类分别对应4个微服务的业务逻辑
-
数据库信息的配置文件:src/main/resources/jdbc.properties
时序图
Ok, 赶紧动手, Make It Happen!