This project demonstrates how to use Seata starter to complete the distributed transaction access of spring cloud applications.
[Seata](https://github.com/seata/seata) It is Alibaba open source distributed transaction middleware, which solves the distributed transaction problem in the microservice scenario in an efficient and non-invasive way.
## Project description
This project demonstrates how to use Seata Starter to complete the distributed transaction access of Spring Cloud Alibaba application.
[Seata](https://github.com/seata/seata) It is Alibaba's open source distributed transaction middleware, which solves the distributed transaction problems faced by micro-service scenarios in an efficient and zero-intrusion way.
## Preparations
Before running this example, you need to complete the following steps:
1. Configure the database
2. Create UNDO_ LOG table
3. Create the database tables needed by the business in the example
4. Create the Nacos configuration in the example, data id: `seata.properties` , Group: `SEATA_ Group` (Seata 1.5.1 default group) configuration import [nacos configuration](https://github.com/seata/seata/blob/1.5.0/script/config-center/config.txt)
At seata Add the following [transaction group configuration](https://seata.io/zh-cn/docs/user/configurations.html) required in the example to properties
Since 1.5.1, Seata 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.
### Configuration database
Before you run this sample, you need to complete the following steps:
First, you need a MySQL database that supports the InnoDB engine.
### 1. Configure the database
**NOTE**: In fact, Seata supports different applications that use totally unrelated databases, but here we chose to use only one database for a simple demonstration of one principle.
> Seata **Notice** actually supports disparate databases for different applications, but Mysql was chosen here for a simple demonstration of how Seata can be used in a Spring Cloud application.
Will application in the resources directory of the `account-server`, `order-service`, `storage-service` three applications. The following configuration in the yml file is modified to the actual configuration in your running environment.
Modify the following configuration in the files under the `application.yml` resources directory in the three applications `account-server`, `order-service`, `storage-service` to the database configuration in the local environment.
```
base:
@ -48,15 +25,14 @@ base:
port: your mysql server listening port
username: your mysql server username
password: your mysql server password
```
### Create undo_ Log table
#### Create the undo _ log table
Seata AT Mode Need to use undo_ Log table.
Seata AT mode requires the undo_log table.
``` $sql
-- Notice here that 0.3.0+ increases the unique index ux_ Undo_ Log
```sql
-- Note that 0.3.0+ adds unique index ux_undo_log here
### Database tables needed to import seata-server DB schema
Initialize in database [global_table、branch_table、lock_table、distributed_lock](https://github.com/seata/seata/blob/1.5.0/script/server/db/mysql.sql)
```$sql
#### Import the database tables required by the seata-server db schema
Initializing [global_table、branch_table、lock_table、distributed_lock](https://github.com/seata/seata/blob/1.8.0/script/server/db/mysql.sql) in the database
```sql
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
### Start Seata Server This describes SpringBoot and download server in two ways
### 2. Configure Nacos
1.Run seata-server to start Seata server
The example uses Nacos as the configuration and the registry storage mode is: DB uses MySQL
> Spring Cloud Alibaba is adapted with Nacos 2.2.3. In this example, Nacos 2.2.3 is used as the configuration center component of Seata.
2. Or click on this page GitHub, the official website of [Seata](https://github.com/seata/seata/releases ), download the latest version of Sata Server.
Enter the bin directory after unzipping and execute the following command to start with all the startup parameters optional.
Create Nacos configuration for Seata: data-id: `seata.properties`, Group: `SEATA_GROUP` (default grouping for seata 1.8.0), import
```$shell
sh seata-server.sh -p $LISTEN_PORT -m $MODE(file or db) -h $HOST -e $ENV
Add the following configuration items required in the application example to the `seata.properties` configuration file: [事务群组配置](https://seata.io/zh-cn/docs/user/configurations.html)
-m storage mode, optional values: file, db. File is for single-point mode and DB is for HA mode. When using DB storage mode, you need to modify the database configuration of the store configuration node in the configuration and initialize [global_table, branch_table, and
-h is used to solve seata-server and business side cross-network problems. The configured host value is displayed directly to the registry service available address host, which needs to be configured as public network IP or NATIP when cross-network. If both are in the same local area network, no configuration is required
-e for multi-environment configuration center isolation
Start Seata Server with the following command
```$shell
sh seata-server.sh -p 8091 -m file
### 3. Start Seata-server
> Seata 1.5.1 supports console local access. Console address: http://127.0.0.1:7091, you can view the information about the transaction being executed and the global lock information through the built-in console of Seata. When the transaction is finished, the relevant information will be deleted.
Modify `seata-server-1.8.0\conf\application.yml` the following configuration items in the configuration file:
- Comment `group: SEATA_GROUP`
- Add Nacos username and password
```yml
seata:
# nacos configuration
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace:
# group: SEATA_GROUP
username: nacos
password: nacos
context-path:
data-id: seataServer.properties
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key:
#secret-key:
registry:
# nacos configuration
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
# group: SEATA_GROUP
namespace:
cluster: default
username: nacos
password: nacos
```
**Note** If you modified the endpoint and the registry uses the default file type, remember the file you need in each of the sample projects. In the conf`file, modify the value of grouplist (when registry.type or config.type in registry.conf is file, the file name in the internal file node is read; if type is not file, the data is read directly from the registry configuration center for the corresponding metadata of the configuration type), Nacos is recommended as the configuration registry.
> **Notice**
> Nacos 2.2.3 enables authentication. Configuration `username` and `password` properties are required, otherwise login fails. For more Nacos 2.2.3 related configurations, refer to `nacos-example`.
> **The Nacos service registration group when seata-server is started must be consistent with the group in the sample application, otherwise an error that seata-server cannot be found will occur!**
> For more information about the configuration of Seata-server with Nacos as the configuration center, please refer to https://seata.io/zh-cn/docs/ops/deploy-by-docker-compose/#nacos-db.
## Run Example
### 3. Start Seata-server
Run the Main functions of the three applications `account-server`, `order-service`, `storage-service` and `business-service`, respectively, to start the example.
Windows:
```cmd
./seata-server.bat
```
After launching the example, the following URLs are accessed through the GET method of HTTP to validate scenarios where other services are invoked through RestTemplate and FeignClient in `business-service` respectively.
Linux/Mac
```$xslt
```shell
sh seata-server.sh
```
For more configuration startup parameters, please refer to https://seata.io/zh-cn/docs/user/quickstart/#%E6%AD%A5%E9%AA%A4-4-%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1.
**Notice** If you change the endpoint and the registry uses the default file type, remember that in the `file.conf` file in each sample project, Modify the value of grouplist (when the registry. Type or config. Type in the registry. Conf is file, the file name in the internal file node will be read. If the type is not file, the data will be directly read from the registration configuration center of the corresponding metadata of the configuration type. It is recommended to use nacos as the configuration registration center.
## Run the sample
Start the sample by running `account-server` the Main functions of the, `order-service`, `storage-service`, and `business-service` applications separately.
After starting the sample, access the following URL through the GET method of HTTP to verify `business-service` the scenarios of calling other services through RestTemplate and FeignClient in respectively.
```shell
http://127.0.0.1:18081/seata/feign
http://127.0.0.1:18081/seata/rest
```
## How do I verify the success of a distributed transaction?
When a service interface is invoked, two types of returns are possible
## How do I verify that a distributed transaction is successful?
### Whether Xid information was successfully transmitted
### Xid information passed successfully
In the Controller of the three services `account-server`, `order-service` and `storage-service`, the first logic executed is to output the Xid information in the 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 consistent. This indicates that the transfer and restore of Seata's Xid are normal.
### Consistency of data in database
In `account-server` the Controllers of, `order-service`, and `storage-service` services, the first logic to be executed is to output the Xid information in the RootContext. If the correct Xid information is output, that is, it changes every time. And that Xid of all the services in the same invocation are the same. Then it indicates that the passing and restoring of Seata's Xid is normal.
In this example, we simulate a scenario where a user purchases goods, StorageService is responsible for deducting the inventory quantity, OrderService is responsible for saving the order, and AccountService is responsible for deducting the user account balance.
### Whether the data in the database is consistent
To demonstrate the sample, we used Random in OrderService and AcountService. NextBoolean () randomly throws exceptions, simulating a scenario in which exceptions occur randomly when a service is invoked.
In this example, we simulate a scenario in which a user purchases goods. The Storage Service is responsible for deducting the inventory quantity, the Order Service is responsible for saving the order, and the Account service is responsible for deducting the balance of the user's account.
If the distributed transaction is valid, then the following equation should be true
To demonstrate the sample, we use Random. NextBoolean () to randomly throw exceptions in Order Service and AccountService, simulating a scenario where exceptions randomly occur during service invocation.
If a distributed transaction is in effect, then the following equation should hold
- User Original Amount (1000) = User Existing Amount + Goods Unit Price (2) * Order Quantity * Goods Quantity per Order (2)
- User's original amount (1000) = user's existing amount + unit price of goods (2) *Number of orders* quantity of goods per order (2)
- Initial Quantity of Goods (100) = Existing Quantity of Goods + Order Quantity * Quantity of Goods per Order (2)
- Initial quantity of goods (100) = Quantity on hand of goods + Order quantity * Quantity of goods per order (2)
## Support points for Spring Cloud
- Service providers that provide services through Spring MVC can automatically restore the Seata context when they receive HTTP requests with Seata information in the header.
- Service providers that provide services through Spring MVC can automatically restore the Seata context when they receive an HTTP request with Seata information in the header.
- Support for automatic delivery of Seata context when service callers invoke through RestTemplate.
- Support the automatic passing of the Seata context when the service caller invokes through the RestTemplate.
- Supports automatic delivery of the Seata context when a service caller invokes through a FeignClient.
- Support the automatic passing of the Seata context when the service caller calls through FeignClient.
- Supports scenarios where both SeataClient and Hystrix are used.
- Scenarios where SeataClient and Hystrix are used together are supported.
- Supports scenarios used by both SeataClient and entinel.
- Scenarios where SeataClient and Sentinel are used together are supported.