add seata doc

pull/2633/head
windwheel 3 years ago
parent 4f6e56dafd
commit a451fc554e

@ -0,0 +1,63 @@
== Spring Cloud Alibaba Seata
=== Seata 介绍
Seata是一个分布式事务框架, 用于保证在微服务架构下每个服务的数据一致性
=== 如何使用seata
如果要在您的项目中引入 Seata使用 group ID 为 `com.alibaba.cloud` 和 artifact ID 为 `spring-cloud-starter-alibaba-seata` 的 starter。
```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
```
在运行[spring-cloud-alibaba-examples/seata-example](https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/seata-example)之前,您需要完成以下步骤:
- 1.保证 本地已经运行```nacos-server ```在 ```8848```端口
- 2.根据 ```spring-cloud-alibaba-examples/seata-example```下的 ```all.sql ```配置数据库
- 3.根据选择的事务模式,创建[事务日志表](https://github.com/seata/seata/tree/develop/script/client) 比如默认为AT模式则进入at/db下选择对应的数据库脚本执行
- 4.创建 seata事务相关的[状态记录表](https://github.com/seata/seata/tree/develop/script/server/db) ```global_table```、```branch_table```、```lock_table```、```distributed_lock```
- 5.创建```spring-cloud-alibaba-examples/seata-example```所需的数据库表
- 6.启动```seata-server```
- 7.创建```spring-cloud-alibaba-examples/seata-example```中的Nacos配置data id: seata.properties, Group: SEATA_ Group(Seata 1.5.1 默认组) 配置导入nacos配置在seata属性中添加示例中需要 的如下事务组配置
```txt
service.vgroupMapping.order-service-tx-group=default
service.vgroupMapping.account-service-tx-group=default
service.vgroupMapping.business-service-tx-group=default
service.vgroupMapping.storage-service-tx-group=default
```
- 8.根据seata官方提供的[seata-server.jar](https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html) 启动Seata Server
- 9.在本地启动 ```spring-cloud-alibaba-examples/seata-example```文件夹下的子服务 ``` business-service```, ```order-service ```, ```storage-service ```,最后启动全局事务控制服务 ``` account-service```
=== Seata Dashboard
Seata 1.5.1支持Seata控制台本地访问控制台地址 ```http://127.0.0.1:7091```
通过Seata控制台可以观察到正在执行的事务信息和全局锁信息并且在事务完成时删除相关信息。
=== 如何验证分布式事务的成功?
### Xid信息是否传输成功
在四个服务的```Controller```中```account-service``````order-service```,```business-service```,```storage-service``` 首先```storage-service```执行的逻辑是输出```RootContext```中的```Xid```信息。如果看到输出了正确的```Xid```信息,每次都在变化,同一个调用中所有服务的```Xid```是一致的。这表明```Seata```的```Xid```的转移和恢复是正常的。
### 数据库中数据的一致性
在这个例子中我们模拟一个用户购买商品的场景StorageService 负责扣除库存数量OrderService 负责保存订单BusinessService 负责扣除用户账户余额,AccountService 负责更新账号的余额,并作为全局事务控制入口。
为了演示示例,我们在 OrderService 和 AcountService 中使用了 Random。NextBoolean() 随机抛出异常,模拟调用服务时随机发生异常的场景。
如果分布式事务是有效的,那么下面的等式应该是正确的
- 用户原始金额1000=用户现有金额+商品单价2*订单数量*每个订单的商品数量2
- 初始商品数量 (100) = 现有商品数量 + 订单数量 * 每个订单的商品数量 (2)
=== Spring Cloud 支持点
- 通过 Spring MVC 提供服务的服务提供者在收到 HTTP 请求时,可以自动恢复 Seata 上下文,该请求在 header 中包含 Seata 信息。
- 当服务调用者通过 RestTemplate 调用时,支持自动传递 Seata 上下文。
- 当服务调用者通过 FeignClient 调用时,支持自动传递 Seata 上下文。
- 支持同时使用 SeataClient 和 Hystrix 的场景。
- 支持 SeataClient 和 entinel 使用的场景。

@ -0,0 +1,62 @@
== Spring Cloud Alibaba Seata
=== Introducing Seata
Seata is a distributed transaction framework to ensure the data consistency of each service under the microservice architecture
=== How to use seata
To include Seata in your project, use the starter with group ID `com.alibaba.cloud` and artifact ID `spring-cloud-starter-alibaba-seata`.
````xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
````
Running [spring-cloud-alibaba-examples/seata-example](https://github.com/alibaba/spring-cloud-alibaba/tree/2021.x/spring-cloud-alibaba-examples/seata-example) Before, you need to complete the following steps:
- 1. Ensure that ```nacos-server ``` is running locally on the ```8848``` port
- 2. Configure the database according to ```all.sql ``` under ```spring-cloud-alibaba-examples/seata-example```
- 3. According to the selected transaction mode, create a [transaction log table] (https://github.com/seata/seata/tree/develop/script/client) For example, the default is AT mode, then enter at/db and select the corresponding The database script executes
- 4. Create a [status record table] related to seata transactions (https://github.com/seata/seata/tree/develop/script/server/db) ```global_table```, ```branch_table`` `, ```lock_table```, ```distributed_lock```
- 5. Create the database tables required by ```spring-cloud-alibaba-examples/seata-example```
- 6. Start ```seata-server```
- 7. Create the Nacos configuration in ```spring-cloud-alibaba-examples/seata-example```, data id: seata.properties, Group: SEATA_ Group (Seata 1.5.1 default group) Configuration import nacos configuration in Add the following transaction group configuration required in the example to the seata attribute
```txt
service.vgroupMapping.order-service-tx-group=default
service.vgroupMapping.account-service-tx-group=default
service.vgroupMapping.business-service-tx-group=default
service.vgroupMapping.storage-service-tx-group=default
```
- 8. Start Seata Server according to the official [seata-server.jar](https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html) provided by seata
- 9. Start the sub-services under the ```spring-cloud-alibaba-examples/seata-example``` folder locally ``` business-service```, ```order-service ```, ` ``storage-service ```, and finally start the global transaction control service ``` account-service```
=== Seata Dashboard
Seata 1.5.1 supports Seata console local access console address: ```http://127.0.0.1:7091```
Through the Seata console, you can observe the executing transaction information and global lock information, and delete the relevant information when the transaction is completed.
=== How to verify the success of a distributed transaction?
### Whether the Xid information is successfully transmitted
In the ````Controller``` of the four services ````account-service```, ```order-service```, ```business-service```, ```storage-service` `` First of all, the logic executed by ````storage-service``` is to output the ```Xid``` information in ```RootContext```. If you see that the correct ```Xid``` information is output, it changes every time, and the ```Xid``` of all services in the same call is the same. This indicates that the transfer and recovery of the ```Xid``` of ```Seata``` is normal.
### Consistency of data in the database
In this example, we simulate a scenario in which a user purchases goods. StorageService is responsible for deducting the inventory quantity, OrderService is responsible for saving orders, BusinessService is responsible for deducting the user's account balance, and AccountService is responsible for updating the account balance, which is used as a global transaction control entry.
To demonstrate the example, we use Random in OrderService and AcountService. NextBoolean() throws an exception randomly, simulating a scenario where an exception occurs randomly when calling a service.
If distributed transactions are efficient, then the following equation should be true
- User's original amount (1000) = user's existing amount + product unit price (2) * order quantity * product quantity per order (2)
- Initial Item Quantity (100) = Existing Item Quantity + Order Quantity * Item Quantity per Order (2)
=== Spring Cloud Support Points
- Service providers that provide services through Spring MVC can automatically restore the Seata context when they receive an HTTP request that includes Seata information in the header.
- Supports automatic passing of Seata context when service caller calls via RestTemplate.
- Supports automatic passing of Seata context when service caller calls via FeignClient.
- Supports scenarios using SeataClient and Hystrix at the same time.
- Support for scenarios used by SeataClient and entinel.

@ -0,0 +1,41 @@
CREATE TABLE `account_tbl`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`money` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `storage_tbl`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `commodity_code` (`commodity_code`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `order_tbl`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`commodity_code` varchar(255) DEFAULT NULL,
`count` int(11) DEFAULT '0',
`money` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `undo_log`
(
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

@ -46,6 +46,10 @@
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
</dependencies>
</project>

@ -2,7 +2,15 @@ server.port=18081
spring.application.name=business-service
spring.cloud.nacos.discovery.server-addr=localhost:8848
# The following configuration can be omitted.
spring.datasource.name="businessDataSource"
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://xxx:3306/seata?useSSL=false&serverTimezone=UTC
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.druid.max-active=20
spring.datasource.druid.min-idle=2
spring.datasource.druid.initial-size=2
#feign.hystrix.enabled=true
#feign.sentinel.enabled=true
feign.client.config.default.connectTimeout=10000

Loading…
Cancel
Save