seata is an open source distributed transaction solution dedicated to providing high-performance and easy-to-use distributed transaction services. seata will provide users with AT, TCC, SAGA and XA transaction modes, and build a one-stop distributed solution for users. The purpose of this tutorial is to provide a quick start to the case of seata. Please refer to the official cases and documents for details.
Seata server building
In Seata, the transaction manager is a separate service, which can be used out of the box without secondary development. Download address https://github.com/seata/seata/releases . In this case, we use version 2.1.0. After downloading and decompressing, you need to configure the Seata server. You need to configure the file.conf and registry.conf .
among file.conf It is to configure the data storage mode of Seata server and support local documents and databases. This paper uses local file storage directly. The configuration is as follows:
## transaction log store, only used in seata-server store { ## store mode: file,db mode = "file" ## file store property file { ## store location dir dir = "sessionStore" # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions maxBranchSessionSize = 16384 # globe session size , if exceeded throws exceptions maxGlobalSessionSize = 512 # file buffer size , if exceeded allocate new buffer fileWriteBufferCacheSize = 16384 # when recover batch read size sessionReloadReadSize = 100 # async, sync flushDiskMode = async } ## database store property db { ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc. datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" url = "jdbc:mysql://127.0.0.1:3306/seata" user = "mysql" password = "mysql" minConn = 5 maxConn = 30 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 } }
registry.conf It is to configure the registry of Seata server. This case is registered on eureka.
registry { # file ,nacos ,eureka,redis,zk,consul,etcd3,sofa type = "eureka" nacos { application = "seata-server" serverAddr = "localhost" namespace = "" cluster = "default" username = "" password = "" } eureka { serviceUrl = "http://localhost:8761/eureka" application = "default" weight = "1" } ... }
Business code initialization
go Official website To download the code, you can also go to the case sorted out in this article. Download address: https://github.com/forezp/distributed-lab/tree/master/seata-sample
Project introduction
After downloading, the file directory of the project project is as follows. There are 5 projects in total, including eureka (Registration Center), business (transaction service), storage (inventory service), order (order service) and account (account service). Seata server and other four business services need to be registered with eureka. sql directory is the script to initialize sql. The directory structure of the project is as follows.
seata-sample ├── account ├── bussiness ├── eureka ├── order ├── pom.xml ├── sql └── storage
Initialize sql
Create the database of seata in the database, and import the database script under the sql directory.
Configuration changes
After introducing the sdk of seata into the business code, you need to configure file.conf and registry.conf , see the code in the source code. stay application.properties Configure mysql connection in:
spring.cloud.alibaba.seata.tx-service-group=my_test_tx_group spring.datasource.url=jdbc:mysql://127.0.0.1:3306/seatatest?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456
Start up works
Start Seata server, euraka, business, storage, order, account project in turn. Address to visit eureka: http://localhost:8761 /, you can see that all services are registered with eureka.
When you start the business service, the following data is inserted into the database:
@PostConstruct public void initData() { jdbcTemplate.update("delete from account_tbl"); jdbcTemplate.update("delete from order_tbl"); jdbcTemplate.update("delete from storage_tbl"); jdbcTemplate.update("insert into account_tbl(user_id,money) values('U100000','10000') "); jdbcTemplate.update("insert into storage_tbl(commodity_code,count) values('C100000','200') "); }
test
seata official has written the code logic, just test it directly.
curl http://127.0.0.1:8084/purchase/commit
The logic of this interface code is as follows:
@RequestMapping(value = "/purchase/commit", produces = "application/json") public String purchaseCommit() { try { businessService.purchase("U100000", "C100000", 30); } catch (Exception exx) { return exx.getMessage(); } return "Global transaction commit"; }
That is, buy 30 stocks. The current stock and amount are enough, so the transaction is normal.
After completion, you can see the account in the database_ The money with id 1 of TBL will be reduced by 5, order_ A new record will be added in TBL, storage_ The count field with id 1 of TBL is reduced by 1
2020-05-21 16:09:12.388 INFO [AsyncCommitting_1]io.seata.server.coordinator.DefaultCore.doGlobalCommit:240 -Committing global transaction is successfully done, xid = 10.66.40.141:8091:2012236512.
Abnormal transaction rollback occurred
Call the following interface:
curl http://127.0.0.1:8084/purchase/rollback
The logic of this interface code is as follows:
@RequestMapping("/purchase/rollback") public String purchaseRollback() { try { businessService.purchase("U100000", "C100000", 99999); } catch (Exception exx) { return exx.getMessage(); } return "Global transaction commit"; }
The sub interface first deducts the inventory, then deducts the money, finally queries the database, finds that the inventory of the database is negative, throws an exception, and rolls back. After the completion, the data in the database does not change, and the rollback is successful. It can be seen that the distributed transaction rollback operation succeeded.
reference material
http://seata.io/zh-cn/docs/overview/what-is-seata.html