本博客记录 SpringCloud Alibaba 整合 Seata1.4.0版本
目录
一.下载seata server
下载地址:http://seata.io/zh-cn/blog/download.html(官网地址)
Tip:这里我下载的1.4.0的binary类型
二.seata server配置修改
解压下载的 seata server 1.4.0压缩包,分别修改seata-server-1.4.0\seata\conf
目录下的file.conf和registry.conf文件
1.修改file.conf文件
mode = "db"
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://127.0.0.1:3306/seata"
user = "数据库的user"
password = "数据库的password"
}
注意:
(1)mode改为db则表示配置为数据库模式;
(2)driverClassName
如果是mysql8以上则改为com.mysql.cj.jdbc.Driver
(3)url
中的seata是seata服务器需要的数据库,需要在数据库中自己创建seata数据库,同时新建几张表。(这里的表需要去github上下载👇👇)
附件:下载seata数据库需要的表sql文件:
下载地址:https://github.com/seata/seata/tree/1.4.0/script/server/db
(不同版本寻找相应版本对应的sql文件)
2.修改registry.conf文件
前提:
在nacos上创建一个新的命名空间seata
registry {
#file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
loadBalance = “RandomLoadBalance”
loadBalanceVirtualNodes = 10
nacos {
application = “seata-server”
serverAddr = “127.0.0.1:8848”
group = “SEATA_GROUP”
namespace = "3f638da9-62b7-45db-92e0-19af2053e996"
cluster = “default”
username = "nacos"
password = "nacos"
}
}
config {
#file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = “127.0.0.1:8848”
namespace = "3f638da9-62b7-45db-92e0-19af2053e996"
group = “SEATA_GROUP”
username = "nacos"
password = "nacos"
}
}
注意:
(1)type
改为nacos;
(2)namespace
改乘前提自己nacos上创建的seata
的ID;
(3)username
和password
改成你对应nacos的账号密码;
三.启动 seata server
地址:执行seata-server-1.4.0\seata\bin\ 目录下的 seata-server.bat/sh启动
测试:
查看nacos控制台即可看到 seata-server注册进nacos了。
四.修改客户端配置并注入nacos
1.配置文件config.txt
(1)下载
下载地址:https://github.com/seata/seata/tree/1.4.0/script/config-center
(不同版本寻找不同的config.txt)
(2)将 config.txt文件下载到 seata-server-1.4.0\seata 目录下
(3)修改config.txt配置文件
service.vgroupMapping.edward-service-group=default
# edward-service-group 为事务组名称
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=root
2.将配置文件config.txt注册nacos配置中心
(1)下载 nacos-config.sh 脚本文件
下载地址:https://github.com/seata/seata/tree/develop/script/config-center/nacos
下载后放到 seata-server-1.4.0\seata\conf文件夹下
(2)执行脚本
sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 命名空间id -u nacos -w nacos
说明:
-h: nacos的hostname
-p: nacos的端口
-g: 配置添加到哪个group下
-t: 配置添加到哪个namespace下
-u: nacos的username
-w: nacos的password
在seata-server-1.4.0\seata\conf文件夹下右击进入git bash,执行如上
脚本;当看到结果failure-count:0时,代表成功(注意修改相关参数)
==============================================================
Complete initialization parameters, total-count:60 , failure-count:0
==============================================================
Init nacos config finished, please start seata-server.
检查nacos的配置列表中已经包含如下配置文件:
五.项目中的使用seata
1.改pom
<dependencies>
<!--nacos-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--seata-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<artifactId>seata-all</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.4.0</version>
</dependency>
<!--feign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--web-actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--mysql-druid-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
注意:seata-all的依赖版本需要和seata server保持一致
2.写配置
(1)写yml
server:
port: 2001
spring:
application:
name: seata-order-service
cloud:
alibaba:
seata:
#自定义事务组名称需要与seata-server中的对应
#(即和config.txt中保持一致)
tx-service-group: edward-tx-group
nacos:
discovery:
server-addr: localhost:8848
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/seata_order?serverTimezone=GMT%2B8
username: root
password: xxxxxx
logging:
level:
io:
seata: info
mybatis:
mapperLocations: classpath:mapper/*.xml
注意:tx-service-group自定义事务组名称需要与seata-server中的对应(即和config.txt中保持一致)
(2)添加file.conf文件
-
下载地址:https://github.com/seata/seata/tree/1.4.0/script/client/conf
-
修改file.conf文件:
service {
#transaction service group mapping
vgroupMapping.edward-tx-group
= “default”
}
注意:这里事务组名称也必须和yml文件以及seata server中的保持一致。
(3)添加registry.conf文件
- 下载地址:https://github.com/seata/seata/tree/1.4.0/script/client/conf
- 修改registry.conf文件
registry {
#file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
loadBalance = “RandomLoadBalance”
loadBalanceVirtualNodes = 10
nacos {
application = “seata-server”
serverAddr = “127.0.0.1:8848”
group = “SEATA_GROUP”
namespace = "3f638da9-62b7-45db-92e0-19af2053e996"
cluster = “default”
username = "nacos"
password = "nacos"
}
}
config {
#file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = “127.0.0.1:8848”
namespace = "3f638da9-62b7-45db-92e0-19af2053e996"
group = “SEATA_GROUP”
username = "nacos"
password = "nacos"
}
}
修改registry.conf文件,与步骤二中修改seata服务器端的registry.conf文件一致。
3.主启动
@EnableDiscoveryClient
@EnableFeignClients
@MapperScan({"com.edward.dao"})
//取消数据源自动创建的配置
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class SeataOrderMainApp2001{
public static void main(String[] args)
{
SpringApplication.run(SeataOrderMainApp2001.class, args);
}
}
4.配置类
(1)修改数据源,改为druid数据源(重要)
package com.edward.config;
import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
@Configuration
public class DataSourceProxyConfig {
@Value("${mybatis.mapperLocations}")
private String mapperLocations;
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource(){
return new DruidDataSource();
}
@Bean
public DataSourceProxy dataSourceProxy(DataSource dataSource) {
return new DataSourceProxy(dataSource);
}
@Bean
public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSourceProxy);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
return sqlSessionFactoryBean.getObject();
}
}
(2)用法
// name随便取,rollbackFor指定哪些异常需要回滚
@GlobalTransactional(name = "edward-tx-group",rollbackFor = Exception.class)
public void create(Order order){
log.info("----->开始新建订单");
//新建订单
orderDao.create(order);
//扣减库存
log.info("----->订单微服务开始调用库存,做扣减Count");
storageService.decrease(order.getProductId(),order.getCount());
log.info("----->订单微服务开始调用库存,做扣减end");
//扣减账户
log.info("----->订单微服务开始调用账户,做扣减Money");
accountService.decrease(order.getUserId(),order.getMoney());
log.info("----->订单微服务开始调用账户,做扣减end");
//修改订单状态,从零到1代表已经完成
log.info("----->修改订单状态开始");
orderDao.update(order.getUserId(),0);
log.info("----->修改订单状态结束");
log.info("----->下订单结束了");
}
Tip:业务相关的数据库需要创建undo_log表,用于seata底层进行回滚时存储镜像文件
下载地址:https://github.com/seata/seata/blob/1.4.0/script/client/at/db/mysql.sql
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
`branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id',
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
作者语录:我学习的版本是0.9.0,1.0以上版本使用有所变动,因此写下此博客用于学习和记录。