無廢話7小時學會使用Spring Cloud Alibaba(7)Seata分佈式事務
一 Seata的作用
開源的分佈式事務解決方案,致力於提供高性能和簡單易用的分佈式事務服務。
二 下載Seata
我這裏用的是最新版的v1.1.0
下載seata-server-1.1.0服務端 :
下載地址:https://github.com/seata/seata/releases/download/v1.1.0/seata-server-1.1.0.zip
1.1.0版本下的conf文件夾:
三 配置Seata
1.seata-server-1.1.0\seata\conf文件夾下修改file.conf
(1).service模塊
注意: seata1.1.0版本是沒有這個模塊的(seata0.9.0版本是有的),所以我們需要添加這個模塊,我直接下載了個seata0.9.0版本的,把裏面的service模塊直接拷貝過來,如下:
service {
#vgroup->rgroup
vgroup_mapping.my_test_tx_group = "default"
#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"
}
這個裏面要注意了,seata1.1.0版本修改了名命,需要修改如下:
將vgroup_mapping 改成駝峯 vgroupMapping,
另外我自己重新名命,將my_test_tx_group 改成 study_tx_group
vgroupMapping.study_tx_group = "default"
(2).store模塊
將mode = "file" 改成 mode = "db"
將url = "jdbc:mysql://127.0.0.1:3306/seata"
user = "mysql"
password = "mysql"
改成自己的數據庫連接(數據庫配置後面會講到)
url = "jdbc:mysql://192.168.1.12:3306/seata"
user = "root"
password = "123"
2.seata-server-1.1.0\seata\conf文件夾下修改registry.conf
(1).registry模塊
將type = "file" 改成 type = "nacos"
將serverAddr = "localhost"
改成自己的nacos地址
serverAddr = "192.168.1.14:8848"
(2).config模塊
這個模塊暫時不需要修改,type = "file" 表示從本地讀取file.conf文件(客戶端項目裏面會把這個文件放進去),
後期也可以改成從nacos裏面讀取。
四 數據庫新建庫seata
在192.168.1.12數據庫上新建數據庫seata,並導入db_store.sql腳本,腳本在seata-server-0.9.0\seata\conf目錄裏面,也可以從下面直接拷貝執行
db_store.sql腳本
-- the table to store GlobalSession data
drop table if exists `global_table`;
create table `global_table` (
`xid` varchar(128) not null,
`transaction_id` bigint,
`status` tinyint not null,
`application_id` varchar(32),
`transaction_service_group` varchar(32),
`transaction_name` varchar(128),
`timeout` int,
`begin_time` bigint,
`application_data` varchar(2000),
`gmt_create` datetime,
`gmt_modified` datetime,
primary key (`xid`),
key `idx_gmt_modified_status` (`gmt_modified`, `status`),
key `idx_transaction_id` (`transaction_id`)
);
-- the table to store BranchSession data
drop table if exists `branch_table`;
create table `branch_table` (
`branch_id` bigint not null,
`xid` varchar(128) not null,
`transaction_id` bigint ,
`resource_group_id` varchar(32),
`resource_id` varchar(256) ,
`lock_key` varchar(128) ,
`branch_type` varchar(8) ,
`status` tinyint,
`client_id` varchar(64),
`application_data` varchar(2000),
`gmt_create` datetime,
`gmt_modified` datetime,
primary key (`branch_id`),
key `idx_xid` (`xid`)
);
-- the table to store lock data
drop table if exists `lock_table`;
create table `lock_table` (
`row_key` varchar(128) not null,
`xid` varchar(96),
`transaction_id` long ,
`branch_id` long,
`resource_id` varchar(256) ,
`table_name` varchar(32) ,
`pk` varchar(36) ,
`gmt_create` datetime ,
`gmt_modified` datetime,
primary key(`row_key`)
);
執行後如下:
五 Seata註冊到Nacos
啓動Nacos,再啓動Seata,進入Nacos的服務管理-服務列表,會發現有該服務
六 業務集成分佈式事務
1.在3個業務數據庫分別建立對應的回滾日誌表
在用戶數據庫,商品數據庫,訂單數據庫分別導入db_undo_log.sql腳本,腳本在seata-server-0.9.0\seata\conf\目錄下,也可以從下面直接拷貝執行
db_undo_log.sql腳本
-- the table to store seata xid data
-- 0.7.0+ add context
-- you must to init this sql for you business databese. the seata server not need it.
-- 此腳本必須初始化在你當前的業務數據庫中,用於AT 模式XID記錄。與server端無關(注:業務數據庫)
-- 注意此處0.3.0+ 增加唯一索引 ux_undo_log
drop table `undo_log`;
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;
執行後如下:
用戶數據庫:
商品數據庫:
訂單數據庫:
2 微服務配置
(1).pom添加seata包
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<version>2.1.1.RELEASE</version>
<exclusions>
<exclusion>
<artifactId>seata-all</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.1.0</version>
</dependency>
(2).yml修改
cloud:
alibaba:
seata:
#自定義事務組名稱需要與seata-server中的對應
tx-service-group: study_tx_group
(3).resources目錄下添加file.conf文件和registry.conf文件
其實就是將剛纔seata-server-1.1.0\seata\conf文件夾下的兩個文件拷貝過來即可
3.啓動類添加seata自動代理數據源
添加標籤@EnableAutoDataSourceProxy
@EnableAutoDataSourceProxy
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class OrderMain {
public static void main(String[] args) {
SpringApplication.run(OrderMain.class, args);
}
}
4.業務類回滾
@GlobalTransactional
public void save(Order order){
//這個只是測試,用戶買了1件商品,花了10塊錢
//添加訂單
orderDao.save(order);
//異常測試回滾數據
int i =1/0;
//扣賬戶餘額
userFeignService.decrease(order.getUserId(),10);
//扣庫存數量
productFeignService.decrease(order.getProductId(),order.getAmount());
}