seata+nacos+springboot2.x整合解决分布式事务一致性问题方案

选型:seata1.4+nacos1.1.3+springboot2.x

1.nacos下载安装

nacos下载:nacos下载
安装启动文档:安装启动文档
启动 linux::sh startup.sh -m standalone
window: startup.bat -m standalone

打开浏览器 localhost:8848/nacos/index.html
账号密码: nacos nacos
在这里插入图片描述

2.下载seata1.4并安装启动

seata下载:下载地址
解压修改 conf/registry.conf 配置,注意seata不同版本配置名称不一样,尽量与我版本一致:

registry {
  #支持 file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  #注意如果选type = "nacos", 那么同目录下的file.conf配置不生效,我就这里遇到坑了
  #需要的配置会去读nacos的配置列表,后面会导入
  type = "nacos"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  nacos {
    # application 版本不同名称也不同,老点的版本好像是"seataAddr"
    application = "seata-server"
    serverAddr = "127.0.0.1:8848"
    group = "SEATA_GROUP"
    namespace = ""
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"

  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
  }
}

创建文件 conf/nacos-config.txt配置

transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.thread-factory.boss-thread-prefix=NettyBoss
transport.thread-factory.worker-thread-prefix=NettyServerNIOWorker
transport.thread-factory.server-executor-thread-prefix=NettyServerBizHandler
transport.thread-factory.share-boss-worker=false
transport.thread-factory.client-selector-thread-prefix=NettyClientSelector
transport.thread-factory.client-selector-thread-size=1
transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread
transport.thread-factory.boss-thread-size=1
transport.thread-factory.worker-thread-size=8
transport.shutdown.wait=3
#注意:seata版本1.0以前vgroup_mapping,1.0以后vgroupMapping.XXX填入你的事务组
#注意事务组跟你项目配置文件中填一致
service.vgroupMapping.account-service-seata-service-group=default
service.vgroupMapping.business-service-seata-service-group=default
service.vgroupMapping.my_test_tx_group=default
service.vgroupMapping.order-service-seata-service-group=default
service.vgroupMapping.storage-service-seata-service-group=default
service.enableDegrade=false
service.disable=false
service.max.commit.retry.timeout=-1
service.max.rollback.retry.timeout=-1
client.async.commit.buffer.limit=10000
client.lock.retry.internal=10
client.lock.retry.times=30
store.mode=db
store.file.dir=file_store/data
store.file.max-branch-session-size=16384
store.file.max-global-session-size=512
store.file.file-write-buffer-cache-size=16384
store.file.flush-disk-mode=async
store.file.session.reload.read_size=100
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.datasource=druid
store.db.dbType=mysql
store.db.url=jdbc:mysql://127.0.0.1:3306/globalsession?useUnicode=true
store.db.user=username
store.db.password=password
store.db.minConn=3
store.db.maxConn=10
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
recovery.committing-retry-period=1000
recovery.asyn-committing-retry-period=1000
recovery.rollbacking-retry-period=1000
recovery.timeout-retry-period=1000
transaction.undo.data.validation=true
transaction.undo.log.serialization=jackson
transaction.undo.log.save.days=7
transaction.undo.log.delete.period=86400000
transaction.undo.log.table=undo_log
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registry-type=compact
metrics.exporter-list=prometheus
metrics.exporter-prometheus-port=9898

创建nacos-config.sh命令

#!/usr/bin/env bash
if [ $# != 1 ]; then
echo "./nacos-config.sh nacosIp"
exit -1
fi

nacosIp=$1
echo "set nacosIp=$nacosIp"
error=0

for line in $(cat nacos-config.txt)

do

key=${line%%=*}
value=${line#*=}
echo "\r\n set "${key}" = "${value}

result=`curl -X POST "http://$nacosIp:8848/nacos/v1/cs/configs?dataId=$key&group=SEATA_GROUP&content=$value"`

if [ "$result"x == "true"x ]; then

  echo "\033[42;37m $result \033[0m"

else

  echo "\033[41;37 $result \033[0m"
  let error++

fi

done


if [ $error -eq 0 ]; then

echo  "\r\n\033[42;37m init nacos config finished, please start seata-server. \033[0m"

else

echo  "\r\n\033[41;33m init nacos config fail. \033[0m"

fi

使用命令导入配置到nacos:
nacos-config.sh 127.0.0.1 我的nacos在本机,所以ip是本地。命令后出现一堆导入信息就成功了。可以去nacos配置列表查看导入的配置信息
在这里插入图片描述

导入seate做控制事务管理时的表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;


-- 事务管理的表,可以单独建一个库globalsession
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`)
);

启动 linux::sh seata-server.sh -h 外网地址
window: seata-server.bat -h 外网地址
-h 接外网地址,不要用127.0.0.1,不然可能找不到

如果启动报错:
{XXX} can’t be empty : nacos配置列表的配置缺失,或者配置名称不对,去搜索一下配置列表看看

启动成功,并在nacos服务列表能看到就成功了。在这里插入图片描述

3.配置服务并启动

pom.xml中引入依赖

		<dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <!-- 版本与seata版本一致 -->
            <version>1.4.0</version>
        </dependency>

在springboot项目配置文件中加入:

seata:
  enabled: true
  application-id: account-seata-example
  # 事务群组(在conf/nacos-config.txt配置的)
  tx-service-group: account-service-seata-service-group 
  registry:
    type: nacos
    nacos:
      server-addr: ip:8848
      cluster: default
  config:
    type: nacos
    nacos:
      server-addr: ip:8848
      #与seate conf/registry.conf 中配置的group必须一致
      group: SEATA_GROUP
  enable-auto-data-source-proxy: true
  data-source-proxy-mode: AT

数据源代理配置

/**
 * 数据源代理
 * @author wangzhongxiang
 */
@Configuration
public class DataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }

    @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSource(DataSource druidDataSource){
        return new DataSourceProxy(druidDataSource);
    }

}

启动项目,成功注册seata的标志如下:
register RM success:Resource Manager (RM)资源管理器注册成功
register TM success:Transaction Manager ™事务管理器注册成功
如果没成功回去检查配置,不然全局事务不会生效
在这里插入图片描述全局事务使用方式,在方法上加注解
@GlobalTransactional(timeoutMills = 3000, name = “account-service-seata-service-group”)
timeoutMills 超时时间-毫秒, name-事务组名称,要使用配置过的事务组名称
在这里插入图片描述
seata全局事务管理多个微服务的子事务,但并不依赖子事务的回滚,事务操作会被记录在undo_log表中,在一阶段就直接提交,如果都成功,就全部提交成功;如果有失败的,在二阶段进行回滚,根据undo_log中的记录进行回滚。

以上有不对或者疑问的可以留言交流!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值