Spring Cloud分布式事务
springboot-seata-demo
使用Seata实现微服务系统-分布式事务
Seata介绍
Seata 是一款阿里巴巴开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。
Distributed Transaction Solution with SEATA
@GlobalTransactional
We just need an annotation @GlobalTransactional on business method:
@GlobalTransactional public void purchase(String userId, String commodityCode, int orderCount) { ...... }
Seata使用
Step01-Demo代码
sbm-storage-service,8081 sbm-order-service,8082 sbm-account-service,8083 sbm-business-service,8084
Step02-启动Seata
alibaba_seata/seata/bin
sh seata-server.sh --port 8091 -m file
Step03-初始化数据库
Import.sql
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;
Step04-接口调用
添加@GlobalTransactional注解
Storage-service
Order-service
Step05-新增库存、账户数据
db_storage.storage_tbl
db_account.account_tbl
Step06-发起调用
http://127.0.0.1:8084/api/business/purchase/commit
sbm-business-service
global transaction[172.20.10.2:8091:78204194684674048]
sbm-order-service
order XID 172.20.10.2:8091:78204194684674048
生成订单>>扣减账户可用金额
sbm-account-service
account XID 172.20.10.2:8091:78204194684674048
sbm-storage-service
扣减库存
storage XID 172.20.10.2:8091:78204194684674048
Step07-异常01
故意扣减账户金额失败
Account account = accountMapper.selectByUserId(userId); account.setMoney(account.getMoney().subtract(num)); accountMapper.updateById(account); //TODO:扣减库存失败 int a = 2/0;
订单数据 - 生成
账户金额 - 扣减成功
过一会儿后,异常生成的订单数据和扣减账户金额、库存又一起恢复了。
订单删除
order XID 172.20.10.2:8091:78208542416314368
账户金额恢复
account XID 172.20.10.2:8091:78208542416314368
库存恢复
storage XID 172.20.10.2:8091:78208542416314368
异常
account XID 172.20.10.2:8091:78208542416314368 java.lang.ArithmeticException: / by zero at io.seata.samples.account.service.AccountService.debit(AccountService.java:24) at io.seata.samples.account.controller.AccountController.debit(AccountController.java:21)
Step08- 异常02
故意扣减账户金额失败(异常在入库之前)
Account account = accountMapper.selectByUserId(userId); account.setMoney(account.getMoney().subtract(num)); //TODO:扣减库存失败 int a = 2/0; accountMapper.updateById(account);
【结果】
除了账户金额没有扣减成功,订单数据 - 生成成功,库存数据 - 扣减成功
storage XID 172.20.10.2:8091:78210482646818816
一会儿,订单数据恢复,库存扣减恢复
分布式事务验证成功。