分布式事務 seata-demo
版本介紹
JDK:1.8
spring-cloud.version:Hoxton.SR8
alibaba.version: 2.2.1.RELEASE
seata.version:1.3.0
nacos: 1.3.1
整合步驟
- 下載下傳nacos我下載下傳的nacos-server-1.3.2.zip
- seata我下載下傳的是 seata-server-1.3.0.zip
- 建立資料庫 server 資料庫腳本 同時每一個參與事務的資料庫需要添加一張表 下載下傳位址
- 上傳seata配置到nacos
- 下載下傳nacos-config.sh檔案,放到解壓檔案conf檔案夾下
- 修改conf目錄下file.conf配置檔案,主要是修改自定義事務組名稱,事務日志存儲模式為db,并修改資料庫連接配接資訊
service { #vgroup->rgroup vgroup_mapping.tx-service-group = "default" #修改事務組名稱為:tx-service-group,和用戶端自定義的名稱對應 #only support single node default.grouplist = "127.0.0.1:8091" #degrade current not support enableDegrade = false #disable disable = false #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent max.commit.retry.timeout = "-1" max.rollback.retry.timeout = "-1" } ## transaction log store, only used in seata-server store { ## store mode: file、db、redis mode = "db" ## database store property db { ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc. datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" url = "jdbc:mysql://192.168.240.129:3306/seat_server" user = "root" password = "Root_123456" minConn = 5 maxConn = 30 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 } }
- 修改conf目錄下 registry.conf配置,指明注冊中心為nacos,及修改nacos連接配接資訊。
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { application = "seata-server" serverAddr = "127.0.0.1:8848" group = "default" namespace = "" cluster = "default" username = "nacos" password = "nacos" } } config { # file、nacos 、apollo、zk、consul、etcd3 SEATA_GROUP type = "nacos" nacos { serverAddr = "127.0.0.1:8848" namespace = "default" group = "" username = "nacos" password = "nacos" } }
-
上傳配置到nacos: 在conf目錄下打開git bash here 執行nacos-config.sh
輸入指令 sh nacos-config.sh -h 127.0.0.1
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-sz2R1x3H-1600680512577)(https://oscimg.oschina.net/oscnet/up-a378b7a609d451d9b38c64a910a09e6ae58.png “seata-config”)]
- 建立client服務
- 建立seat_order庫,用來存儲訂單資訊
- 建立seat_storage庫,用來存儲庫存資訊
- 建立seat_account,用來存儲賬戶資訊
- 三個庫添加日志復原表
完整資料庫示意圖

5. 建立seata-order-service(訂單服務),seata-storage-service(庫存服務),seata-account-service(賬戶服務)
配置内容大同小異以order服務的配置為例,修改bootstrap.yml檔案
server:
port: 8180
spring:
application:
name: seata-order-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
username: "nacos"
password: "nacos"
config:
server-addr: 127.0.0.1:8848
username: "nacos"
password: "nacos"
mybatis:
mapperLocations: classpath:mapper/*.xml
修改application.yml檔案
seata:
enabled: true
application-id: seata-order-service
tx-service-group: my_test_tx_group #tx-service-group需要與conf目錄下file.conf檔案下名稱一緻
config:
type: nacos
nacos:
namespace:
serverAddr: 127.0.0.1:8848
group: SEATA_GROUP
username: "nacos"
password: "nacos"
registry:
type: nacos
nacos:
application: seata-server
server-addr: 127.0.0.1:8848
group: SEATA_GROUP
namespace:
username: "nacos"
password: "nacos"
spring:
datasource:
#driver-class-name: com.mysql.jdbc.Driver
username: root
password: 'Root_123456'
url: jdbc:mysql://192.168.240.129:3306/seat_order?characterEncoding=utf-8&useSSL=false
添加主方法
@RestController
@RequestMapping(value = "/order")
public class OrderController {
@Autowired
private OrderService orderService;
/**
* 建立訂單
*/
@GetMapping("/create")
@GlobalTransactional
public CommonResult create(Order order) {
orderService.create(order);
return new CommonResult("訂單建立成功!", 200);
}
}
- 啟動nacos,seata,seata-order-service,seata-storage-service,seata-account-service
2020-09-21 16:17:08.307 INFO 29768 --- [ main] i.s.s.a.GlobalTransactionScanner : Initializing Global Transaction Clients ...
2020-09-21 16:17:08.394 INFO 29768 --- [ main] i.s.core.rpc.netty.NettyClientBootstrap : NettyClientBootstrap has started
2020-09-21 16:17:08.394 INFO 29768 --- [ main] i.s.s.a.GlobalTransactionScanner : Transaction Manager Client is initialized. applicationId[seata-order-service] txServiceGroup[my_test_tx_group]
2020-09-21 16:17:08.403 INFO 29768 --- [ main] io.seata.rm.datasource.AsyncWorker : Async Commit Buffer Limit: 10000
2020-09-21 16:17:08.403 INFO 29768 --- [ main] i.s.rm.datasource.xa.ResourceManagerXA : ResourceManagerXA init ...
2020-09-21 16:17:08.408 INFO 29768 --- [ main] i.s.core.rpc.netty.NettyClientBootstrap : NettyClientBootstrap has started
2020-09-21 16:17:08.408 INFO 29768 --- [ main] i.s.s.a.GlobalTransactionScanner : Resource Manager is initialized. applicationId[seata-order-service] txServiceGroup[my_test_tx_group]
2020-09-21 16:17:08.408 INFO 29768 --- [ main] i.s.s.a.GlobalTransactionScanner : Global Transaction Clients are initialized.
3. 測試分布式事務
庫的初始狀态
通路 http://localhost:8180/order/create?userId=1&productId=1&count=10&money=100
2020-09-21 16:27:22.497 INFO 29768 --- [nio-8180-exec-9] i.seata.tm.api.DefaultGlobalTransaction : Begin new global transaction [192.168.240.1:8091:51345170083352576]
2020-09-21 16:27:22.497 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->下單開始
2020-09-21 16:27:22.508 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中扣減庫存開始
2020-09-21 16:27:22.530 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中扣減庫存結束
2020-09-21 16:27:22.530 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中扣減餘額開始
2020-09-21 16:27:22.543 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中扣減餘額結束
2020-09-21 16:27:22.543 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中修改訂單狀态開始
2020-09-21 16:27:22.550 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中修改訂單狀态結束
2020-09-21 16:27:22.550 INFO 29768 --- [nio-8180-exec-9] c.m.cloud.service.impl.OrderServiceImpl : ------->下單結束
2020-09-21 16:27:22.552 INFO 29768 --- [nio-8180-exec-9] i.seata.tm.api.DefaultGlobalTransaction : [192.168.240.1:8091:51345170083352576] commit status: Committed
2020-09-21 16:27:22.560 INFO 29768 --- [h_RMROLE_1_6_16] i.s.c.r.p.c.RmBranchCommitProcessor : rm client handle branch commit process:xid=192.168.240.1:8091:51345170083352576,branchId=51345170112712704,branchType=AT,resourceId=jdbc:mysql://192.168.240.129:3306/seat_order,applicationData=null
2020-09-21 16:27:22.560 INFO 29768 --- [h_RMROLE_1_6_16] io.seata.rm.AbstractRMHandler : Branch committing: 192.168.240.1:8091:51345170083352576 51345170112712704 jdbc:mysql://192.168.240.129:3306/seat_order null
2020-09-21 16:27:22.560 INFO 29768 --- [h_RMROLE_1_6_16] io.seata.rm.AbstractRMHandler : Branch commit result: PhaseTwo_Committed
2020-09-21 16:27:22.622 INFO 29768 --- [h_RMROLE_1_7_16] i.s.c.r.p.c.RmBranchCommitProcessor : rm client handle branch commit process:xid=192.168.240.1:8091:51345170083352576,branchId=51345170297262080,branchType=AT,resourceId=jdbc:mysql://192.168.240.129:3306/seat_order,applicationData=null
2020-09-21 16:27:22.622 INFO 29768 --- [h_RMROLE_1_7_16] io.seata.rm.AbstractRMHandler : Branch committing: 192.168.240.1:8091:51345170083352576 51345170297262080 jdbc:mysql://192.168.240.129:3306/seat_order null
2020-09-21 16:27:22.622 INFO 29768 --- [h_RMROLE_1_7_16] io.seata.rm.AbstractRMHandler : Branch commit result: PhaseTwo_Committed
資料庫狀态
模拟異常
/**
* 扣減賬戶餘額
*/
@Override
public void decrease(Long userId, BigDecimal money) {
LOGGER.info("------->account-service中扣減賬戶餘額開始");
//模拟逾時異常,全局事務復原
try {
Thread.sleep(30*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
accountDao.decrease(userId,money);
LOGGER.info("------->account-service中扣減賬戶餘額結束");
}
會發現資料庫沒有變化,并且控制台列印日志如下
2020-09-21 16:29:53.921 INFO 29768 --- [nio-8180-exec-3] i.seata.tm.api.DefaultGlobalTransaction : Begin new global transaction [192.168.240.1:8091:51345805197447168]
2020-09-21 16:29:53.921 INFO 29768 --- [nio-8180-exec-3] c.m.cloud.service.impl.OrderServiceImpl : ------->下單開始
2020-09-21 16:29:53.931 INFO 29768 --- [nio-8180-exec-3] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中扣減庫存開始
2020-09-21 16:29:53.957 INFO 29768 --- [nio-8180-exec-3] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中扣減庫存結束
2020-09-21 16:29:53.957 INFO 29768 --- [nio-8180-exec-3] c.m.cloud.service.impl.OrderServiceImpl : ------->order-service中扣減餘額開始
2020-09-21 16:29:56.099 INFO 29768 --- [h_RMROLE_1_8_16] i.s.c.r.p.c.RmBranchRollbackProcessor : rm handle branch rollback process:xid=192.168.240.1:8091:51345805197447168,branchId=51345805231001600,branchType=AT,resourceId=jdbc:mysql://192.168.240.129:3306/seat_order,applicationData=null
2020-09-21 16:29:56.100 INFO 29768 --- [h_RMROLE_1_8_16] io.seata.rm.AbstractRMHandler : Branch Rollbacking: 192.168.240.1:8091:51345805197447168 51345805231001600 jdbc:mysql://192.168.240.129:3306/seat_order
2020-09-21 16:29:56.142 INFO 29768 --- [h_RMROLE_1_8_16] i.s.r.d.undo.AbstractUndoLogManager : xid 192.168.240.1:8091:51345805197447168 branch 51345805231001600, undo_log deleted with GlobalFinished
2020-09-21 16:29:56.143 INFO 29768 --- [h_RMROLE_1_8_16] io.seata.rm.AbstractRMHandler : Branch Rollbacked result: PhaseTwo_Rollbacked
2020-09-21 16:29:56.147 INFO 29768 --- [nio-8180-exec-3] i.seata.tm.api.DefaultGlobalTransaction : [192.168.240.1:8091:51345805197447168] rollback status: Rollbacked
2020-09-21 16:29:56.167 ERROR 29768 --- [nio-8180-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.RetryableException: Read timed out executing GET http://seata-account-service/account/decrease?userId=1&money=100] with root cause
java.net.SocketTimeoutException: Read timed out
...
https://gitee.com/shiliang_feng/seate-demo/tree/master 源碼位址
參考文檔
https://juejin.im/post/6844904001528397831
https://www.pianshen.com/article/32571721859/
官方文檔
https://github.com/seata/seata