若依集成seata分布式事务(AT模式)并以nacos作为配置中心和注册中心(含踩坑)

一、序言

由于使用的是若依的框架,在若依的官网也有说明seata的使用方法,但是自己在写demo的时候,是想结合项目来实现demo,不过seata在本地的部署是参考了seata的官网和若依的官网对seata的使用
以及博客:微服务项目中使用seata,以nacos作为配置中心,很详细
最终在不断的踩坑中,部署和测试完成!

二、版本说明

若依的版本是:3.8.5
nacos服务端的版本是:2.2.8
nacos客户端的版本是:2.1.0
seata服务端的版本是:1.5.2
seata客户端的版本是:2.2.8
PostgreSQL版本:42.2.0

三、下载和安装seata

3.1 下载地址

https://github.com/apache/incubator-seata/releases/download/v1.5.2/seata-server-1.5.2.zip
当然也可以选择其他的版本进行下载,目前最新的版本是2.0.0
2.0.0的版本下载链接
在这里插入图片描述文件不大,小伙伴们就自行去官网下载吧,我这里就不提供了。

3.2 修改配置

我们下载好包之后解压后的目录是这样的:
在这里插入图片描述
主要用到的就是标记为123的文件:

  • 1是要修改的配置文件,
  • 2和3无需修改,2是启动脚本,3是要执行的sql。

3.2.1 执行sql

我们在上面有说下载的seata压缩包中还有一些sql脚本,就是上图中的3,根据若依官网和seata官网,创建数据库需要分为两步走:

  • 第一步:在业务库中创建undo_log表:
    mysql如下:
CREATE TABLE IF NOT EXISTS `undo_log`
(`branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',`xid`           VARCHAR(128) 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 = utf8mb4 COMMENT ='AT transaction mode undo table';
ALTER TABLE `undo_log` ADD INDEX `ix_log_created` (`log_created`);

PostreSQL如下:

CREATE TABLE public.undo_log (branch_id BIGINT NOT NULL,xid varchar(128) NOT NULL,context varchar(128) NOT NULL,rollback_info BIGINT NOT NULL,log_status INT NOT NULL,log_created timestamp NOT NULL,log_modified timestamp NOT NULL,CONSTRAINT ux_undo_log PRIMARY KEY (id)
);comment on column public.undo_log.branch_id is 'branch transaction id';
comment on column public.undo_log.xid is 'undo_log context,such as serialization';
comment on column public.undo_log.context is 'rollback info';
comment on column public.undo_log.rollback_info is 'branch transaction id';
comment on column public.undo_log.log_status is '0:normal status,1:defense status';
comment on column public.undo_log.log_created is 'create datetime';
comment on column public.undo_log.log_modified is 'modify datetime';create UNIQUE index idx_undo_log on public.undo_log using btree (xid, branch_id);
create index ix_log_created on public.undo_log using btree (log_created);
  • 第二步:
    新建一个数据库:seata,在库中创建如下表,对应的sql就是在我们上图中的绿框的3中,根据自己的数据库类型来选择,我这里创建的是pg的数据库:
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS public.global_table
(xid                       VARCHAR(128) NOT NULL,transaction_id            BIGINT,status                    SMALLINT     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                TIMESTAMP(0),gmt_modified              TIMESTAMP(0),CONSTRAINT pk_global_table PRIMARY KEY (xid)
);CREATE INDEX idx_status_gmt_modified ON public.global_table (status, gmt_modified);
CREATE INDEX idx_transaction_id ON public.global_table (transaction_id);-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS public.branch_table
(branch_id         BIGINT       NOT NULL,xid               VARCHAR(128) NOT NULL,transaction_id    BIGINT,resource_group_id VARCHAR(32),resource_id       VARCHAR(256),branch_type       VARCHAR(8),status            SMALLINT,client_id         VARCHAR(64),application_data  VARCHAR(2000),gmt_create        TIMESTAMP(6),gmt_modified      TIMESTAMP(6),CONSTRAINT pk_branch_table PRIMARY KEY (branch_id)
);CREATE INDEX idx_xid ON public.branch_table (xid);-- the table to store lock data
CREATE TABLE IF NOT EXISTS public.lock_table
(row_key        VARCHAR(128) NOT NULL,xid            VARCHAR(128),transaction_id BIGINT,branch_id      BIGINT       NOT NULL,resource_id    VARCHAR(256),table_name     VARCHAR(32),pk             VARCHAR(36),status         SMALLINT     NOT NULL DEFAULT 0,gmt_create     TIMESTAMP(0),gmt_modified   TIMESTAMP(0),CONSTRAINT pk_lock_table PRIMARY KEY (row_key)
);comment on column public.lock_table.status is '0:locked ,1:rollbacking';
CREATE INDEX idx_branch_id ON public.lock_table (branch_id);
CREATE INDEX idx_xid_and_branch_id ON public.lock_table (xid, branch_id);
CREATE INDEX idx_status ON public.lock_table (status);CREATE TABLE distributed_lock (lock_key     VARCHAR(20)  NOT NULL,lock_value        VARCHAR(20)  NOT NULL,expire       BIGINT       NOT NULL,CONSTRAINT pk_distributed_lock_table PRIMARY KEY (lock_key)
);INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO distributed_lock (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);

直接复制后执行就行。

3.2.2 修改application.yml

因为我这里要用nacos做配置和注册中心,所以其余的配置项目就删掉了,这个文件中只需要修改下图中的配置:
在这里插入图片描述
其他的无需修改,那么正确的配置应该是什么样的呢,也是在压缩包里的conf目录下有个application.example.yml文件给出了例子,所以第一次接触可以使用这个例子进行配置,我这里就贴一下我最后的配置结果:

server:port: 7091spring:application:name: seata-serverlogging:config: classpath:logback-spring.xmlfile:path: ${user.home}/logs/seataextend:logstash-appender:destination: 127.0.0.1:4560kafka-appender:bootstrap-servers: 127.0.0.1:9092topic: logback_to_logstashconsole:user:username: seatapassword: seataseata:config:# support: nacos 、 consul 、 apollo 、 zk  、 etcd3type: nacosnacos:server-addr: 127.0.0.1:8848namespace: devgroup: SEATA_GROUPusername: nacospassword: ncs-nacosdata-id: seataServer.propertiesregistry:# support: nacos 、 eureka 、 redis 、 zk  、 consul 、 etcd3 、 sofatype: nacospreferred-networks: 30.240.*nacos:application: seata-serverserver-addr: 127.0.0.1:8848namespace: devgroup: SEATA_GROUPusername: nacospassword: ncs-nacoscluster: CD # 这里可以自定义,一般写成default,我这里就定制一下,写的CD#store:# support: file 、 db 、 redis# mode: file
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'security:secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017tokenValidityInMilliseconds: 1800000ignore:urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

我们可以看到在seata.config.nacos下面有一个data-id=seataServer.properties,这个就需要在nacos中进行配置了.

3.2.3 配置seataServer.properties

那么这个文件的官方文件是从哪里下载的呢?我们回归到seata的官网关于nacos的配置这里
在这里插入图片描述
我这里也粘贴一下github的config.txt的地址吧:https://github.com/apache/incubator-seata/blob/develop/script/config-center/config.txt不过有时候这个不是那么好打开,好在除了在github上下载还有一种更简单方便的方式可以获取到这个文件,在我们最开始下载的seata-1.5.2版本的压缩包里的script目录下的config-center目录下有个config.txt:
在这里插入图片描述

如果可以打开也可以从github下载源文件:
在这里插入图片描述

config.txt的内容看着也有很多内容,乍一看有点懵,要改啥,别慌,我们要改3处地方:
在这里插入图片描述
图中标记为1的就是我要改的,标记为2 的就是我这里要删除的,因为我用的是数据库,用不到redis就删除了redis的配置,小伙伴们可以根据自己的情况进行修改。

不是说3处要修改吗,怎么只说了2处,别急,第3处待会就会闪亮登场啦。

我这里最后修改了1和2处的文件的成果如下:

#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html
#Transport configuration, for client and server
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableTmClientBatchSendRequest=false
transport.enableRmClientBatchSendRequest=true
transport.enableTcServerBatchSendResponse=false
transport.rpcRmRequestTimeout=30000
transport.rpcTmRequestTimeout=30000
transport.rpcTcRequestTimeout=30000
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
transport.serialization=seata
transport.compressor=none#Transaction routing rules configuration, only for the client
service.vgroupMapping.default_tx_group=default
#If you use a registry, you can ignore it
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false#Transaction rule configuration, only for the client
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=true
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
#For TCC transaction mode
tcc.fence.logTableName=tcc_fence_log
tcc.fence.cleanPeriod=1h#Log rule configuration, for client and server
log.exceptionRate=100#Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional.
store.mode=file
store.lock.mode=file
store.session.mode=file
#Used for password encryption
store.publicKey=#If `store.mode,store.lock.mode,store.session.mode` are not equal to `file`, you can remove the configuration block.
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.
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=username
store.db.password=password
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000#These configurations are required if the `store mode` is `redis`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `redis`, you can remove the configuration block.
store.redis.mode=single
store.redis.single.host=127.0.0.1
store.redis.single.port=6379
store.redis.sentinel.masterName=
store.redis.sentinel.sentinelHosts=
store.redis.sentinel.sentinelPassword=
store.redis.maxConn=10
store.redis.minConn=1
store.redis.maxTotal=100
store.redis.database=0
store.redis.password=
store.redis.queryLimit=100#Transaction rule configuration, only for the server
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.distributedLockExpireTime=10000
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

我这里的seataServer.properties文件里的内容如下:

#For details about configuration items, see https://seata.io/zh-cn/docs/user/configurations.html
#Transport configuration, for client and server
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableTmClientBatchSendRequest=false
transport.enableRmClientBatchSendRequest=true
transport.enableTcServerBatchSendResponse=false
transport.rpcRmRequestTimeout=30000
transport.rpcTmRequestTimeout=30000
transport.rpcTcRequestTimeout=30000
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
transport.serialization=seata
transport.compressor=none#Transaction routing rules configuration, only for the client
service.vgroupMapping.default_tx_group=CD
#If you use a registry, you can ignore it
service.default.grouplist=127.0.0.1:8091
service.enableDegrade=false
service.disableGlobalTransaction=false#Transaction rule configuration, only for the client
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=true
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.sagaJsonParser=fastjson
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
#For TCC transaction mode
tcc.fence.logTableName=tcc_fence_log
tcc.fence.cleanPeriod=1h#Log rule configuration, for client and server
log.exceptionRate=100#Transaction storage configuration, only for the server. The file, db, and redis configuration values are optional.
store.mode=file
store.lock.mode=file
store.session.mode=file
#Used for password encryption
store.publicKey=#If `store.mode,store.lock.mode,store.session.mode` are not equal to `file`, you can remove the configuration block.
store.file.dir=file_store/data
store.file.maxBranchSessionSize=16384
store.file.maxGlobalSessionSize=512
store.file.fileWriteBufferCacheSize=16384
store.file.flushDiskMode=async
store.file.sessionReloadReadSize=100#These configurations are required if the `store mode` is `db`. If `store.mode,store.lock.mode,store.session.mode` are not equal to `db`, you can remove the configuration block.
store.db.datasource=druid
store.db.dbType=postgresql
store.db.driverClassName=org.postgresql.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata_?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=root
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.distributedLockTable=distributed_lock
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000#Transaction rule configuration, only for the server
server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.distributedLockExpireTime=10000
server.xaerNotaRetryTimeout=60000
server.session.branchAsyncQueueSize=5000
server.session.enableBranchAsyncRemove=false
server.enableParallelRequestHandle=false#Metrics configuration, only for the server
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

我这里的数据库用的是pg数据库,主要是项目上用的是pg,如果是mysql的话,就是这样了:

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

其他的不变,文件内容准备好了,那么刚才说要在nacos中进行配置,下面就开始在nacos中配置了。
我们只需要在nacos中创建一个seataServer.properties的配置就可以了。
根据前面在application.yml中的配置,我在nacos中增加了dev的命名空间,所以我这里也需要把配置先在dev的空间里放一份。
那么怎么创建的nacos的这个配置呢,看下对应关系吧:
在这里插入图片描述
把前面准备好的seataServer.properties的内容粘贴到配置内容即可。

:我这里nacos的配置的Data Id和Group的值是灰色不可修改是因为我之前增加过了,为了截图就编辑进来的。

3.2.4 启动seata

所有的准备工作都做好了,只欠东风了,怎么启动seata,从我们下载的seata的压缩包里可以看到,里面有个bin目录,就是我最开始的截图中的黄色框的2处,里面有bat和sh的启动脚本,如果是window直接双击seata-server.bat就可以,如果是mac系统,就使用命令来执行,在前面给出的seata的官网也有对应的命令:
在这里插入图片描述
进入bin目录后我使用的命令是:sh seata-server.sh -p 8091 -h 127.0.0.1 -m db
因为我们的模式是db模式,不过我也试过直接使用:./seata-server.sh也是可以的,毕竟那些参数都有默认的,至于模式我感觉是自己识别到了。
执行完之后会告诉你日志在哪里看,也可以看下进程:ps -ef|grep seata,如果这个时候发现没有seata的进程,那就需要看下日志了,我的是没有启动成功的:
在这里插入图片描述
日志显示无法识别VM参数,那就把这个参数去掉,但去掉之后,又接二连三的有其他的参数说也无法识别,所以最后需要删除这5个参数才能把这个问题解决掉:
在这里插入图片描述
至于我这里为啥要删除才行,应该是jdk版本的问题,大家可以根据自己的情况来处理。
当我解决了这个问题启动seata之后又出现了个问题:
在这里插入图片描述
参考了这篇博客:postgresql不支援 10 验证类型
于是我死马当活马医,从pg的官网下载了稍微新一旦的pg包:https://jdbc.postgresql.org/download/放到了lib库下面:
在这里插入图片描述
原来的版本是:
在这里插入图片描述
我本来是没有删掉这个低版本,新的和老的都保留着,但是发现杀掉进程重启还是不行,于是只能把老的版本删掉了。删掉后重新启动后看日志,发现可以启动成功了:
在这里插入图片描述
我们看下nacos是否注册成功了:
在这里插入图片描述
服务详情:
在这里插入图片描述
至此,seata的部署已经完成了!!!可喜可贺!

四、若依集成seata

4.1 引入seata依赖

我这里没有像若依的官网说的那样,引入若依的seata依赖,而是自己单独在用到seata的模块(ruoyi-system)引入的seata-all的依赖:

 <!--openfeign 远程调用--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--分布式事务seata-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

因为要测试调用另外一个服务,这里使用openfeign进行远程调用。

4.2 微服务配置

因为我把所有的服务配置都挪到nacos中了,做了配合nacos进行多环境profile的配置,感兴趣可以参考我前不久写的这篇文章:若依Cloud项目配合nacos进行多环境profile的配置也是在这个服务进行整合的。

我的微服务中的yml配置如下:

# seata配置
seata:enabled: trueapplication-id: ${spring.application.name}tx-service-group: default_tx_groupenable-auto-data-source-proxy: false# seata nacos注册中心配置registry:type: nacosnacos:application: seata-serverserver-addr:  127.0.0.1:8848group: SEATA_GROUPnamespace: dev# seata nacos配置中心配置config:type: nacosnacos:server-addr:  127.0.0.1:8848group: SEATA_GROUPnamespace: devdata-id: seataServer.properties

可能有些小伙伴要奇怪了我这里没有写nacos的帐号密码,因为本身我们就是在nacos中配置的,nacos的配置是在微服务中的bootstrap.yml中,所以这里就不用重复写了。这里也可以参考我刚才提到的多环境配置的部分。

4.3 配置事务组

3.2.3 配置seataServer.properties节中说修改seataServer.properties中有3处要修改,这里就要说到了,在微服务的yml配置中有个seata.tx-service-group=default_tx_group,这里配置需要在seataServer.properties保持一致:
在这里插入图片描述
画黄框中的内容要和微服务的yml配置中有个seata.tx-service-group的值一致!
在这里插入图片描述
至于seataServer.properties中的配置:service.vgroupMapping.default_tx_group=CD的值是CD,这个是我自己定义的,也可以写成default,但要保证和3.2.2 修改application.yml中的cluster的值保持一致:
在这里插入图片描述
这里seata.registry.nacos.cluster=CDservice.vgroupMapping.default_tx_group=CD值保持一致,如果不保持一致会报错:
no available service found in cluster ‘default’, please make sure registry config correct and keep your seata server running

4.4 启动服务

A服务的启动日志为:
在这里插入图片描述
seata服务端的日志为:
在这里插入图片描述

B服务的启动日志为:
在这里插入图片描述
seata服务端的日志为:
在这里插入图片描述

4.5 实践A服务调用B服务回滚

A服务就是若依服务,B服务是另外一个服务

4.5.1 postman发起请求

curl --location --request POST 'http://localhost:8080/system/config/add' \
--header 'Content-Type: application/json' \
--data-raw '{"configId":10,"configName":"测试分布式-远程调用","configKey":"sys.test.seata","configValue":"fanf","configType":"N","remark":"看看能不能插入成功"
}'

4.5.2 A服务接收请求

Controller层:
在这里插入图片描述
Service层:
在这里插入图片描述

注⚠️:我这里特意模拟了一下,a服务先插入,再调用b服务的插入服务,当b服务插入失败,a服务的插入应该是不成功的。因为对于b服务而言,tcm_code表中的create_person字段是比填字段,如果缺少肯定会抛异常,那
a的插入肯定得回滚才是对的。

feign调用:
在这里插入图片描述

4.5.3 b服务接收RPC远程调用

Controller层:
在这里插入图片描述
Service层:
在这里插入图片描述当把两个服务都启动之后,使用postman进行调用,b服务会抛出缺失必填字段的异常:
在这里插入图片描述
再看下A服务的日志:
在这里插入图片描述
这里实现是执行了插入的操作的,但实际上数据库里并没有真的插入,往下接着看日志:
在这里插入图片描述
当A服务接收到B服务抛出异常之后,就回滚了,看下A服务要插入的sys_confg表的数据也是没有的,说明是回滚成功了的。

4.6 一些问题

我在集成过程中遇到的一些问题都写在下面的博客中了,小伙伴可做参考:
若依框架集成seata分布式事务的一些幺蛾子

-------------------------知道的越多,不知道的越多--------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1409800.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

礼赞劳动节,致敬劳动者。节日随想:疾笔耕耘也是一种劳动方式。

马克思也快诞辰了206年了&#xff0c;恩格斯领导的第二国际通过的决议节日也迎来了134岁的生日了&#xff0c;我也继续在劳动的路上。 五月是值得纪念的日子&#xff0c;作为一名无上光荣的分子&#xff0c;无比仰慕崇拜的两位先驱前辈大胡子&#xff0c;其一 生于斯&#xff0…

(学习日记)2024.05.08:UCOSIII第六十二节:常用的结构体(os.h文件)第一部分

之前的章节都是针对某个或某些知识点进行的专项讲解&#xff0c;重点在功能和代码解释。 回到最初开始学μC/OS-III系统时&#xff0c;当时就定下了一个目标&#xff0c;不仅要读懂&#xff0c;还要读透&#xff0c;改造成更适合中国宝宝体质的使用方式。在学完野火的教程后&a…

blender(布兰德)下载安装-windows系统安装

1.简单介绍 这些介绍都是一些百科或官网提供的内容&#xff0c;直接搜索对应的信息后即可看到。Blender&#xff08;布兰德&#xff09;是一款永久开源免费的3D创建套件。支持整个3D创作流程&#xff1a;建模、雕刻、骨骼装配、动画、模拟、实时渲染、合成和运动跟踪&#xff…

Java Maven 编译资源文件拷贝错误 dirCompressed.zip failed with MalformedInputException:

完整的错误信息为&#xff1a; [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.3.1:resources (default-resources) on project core-java-io: filtering C:\WorkDir\Repository\iSharkfly-Docs\java-tutorials\core-java-modules\core-ja…

Microsoft.NET 框架程序设计 —— 共享程序集

文件版本是一个很难解决的问题。实际上,如果仅仅在一个文件中将其某一位从0改变到1、或者从1改变到0,我们便不能绝对保证使用原来文件的代码和它使用新版文件时的行为一样。这是因为许多应用程序都会有意或者无意地引入bug。如果一个文件的后续版本修复了一个bug,应用程序便…

第12章 软件测试基础(第一部分)概念、质量保证、测试用例、测试执行过程

一、软件测试 &#xff08;一&#xff09;定义 动态验证计算机程序对有限的测试用例集是否可产生期望的结果的过程。测试计划是描述了要进行的测试活动的范围、方法、资源和进度的文档。编写测试计划目的&#xff1a;使测试工作顺利进行、使项目参与人员沟通更舒畅、使测试工…

翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习六

合集 ChatGPT 通过图形化的方式来理解 Transformer 架构 翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习一翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深度学习二翻译: 什么是ChatGPT 通过图形化的方式来理解 Transformer 架构 深…

用FPGA+DAC输出“心”形波

1.前言 之前在做信号处理的时候整了一下活&#xff0c;用FPGADAC&#xff08;数模转换器&#xff09;&#xff0c;输出了一个爱心形状的波形&#xff0c;今天整理资料的时候偶然发现了他&#xff0c;现在把他分享出来。当时将DAC的输出接在示波器上显示如下图所示&#xff1a; …

雅思备考经验(个人向)

IELTS备考经验(个人向) 备考时长约1个月, 首考6.5(6), 虽然没考到小分6.5, 我也接受了, 过段时间再考吧. 机考or纸笔 雅思有机考也有传统的纸笔考试形式, 个人更推荐机考, 原因如下: 机考口语和笔试一般都在同一天, 而纸笔的口语和笔试一般不在同一天, 有时候可能会差一个…

工业三废数据集(工业烟粉尘排放量、工业二氧化硫排放量、工业废水排放量)2006-2021年

01、数据介绍 工业三废是指工业生产过程中排出的废气、废水和废渣 工业二氧化硫排放量指企业在燃料燃烧和生产工艺过程中排入大气的二氧化硫数量。 工业烟粉尘排放量是指企业在生产工艺过程中排放的烟尘和粉尘等颗粒物重量。 工业废水排放量是指企业在生产过程中产生的废水…

GEE必须会教程—植被覆盖度(FVC)计算(代码分享)

植被覆盖度&#xff08;FVC&#xff09;的计算是遥感上非常重要的一个研究领域&#xff0c;因事务繁忙&#xff0c;今天小编先带来FVC的全文代码&#xff0c;给大家试试&#xff0c;后期会出一期专栏进行代码的详细介绍&#xff1a; 今天福利满满&#xff0c;直接上代码&#…

信息技术内涵及意义

一、信息技术及其演进趋势 &#xff08;一&#xff09;信息技术概况概念 信息技术&#xff08;Information Technology&#xff0c;IT&#xff09;指“应用在信息加工和处理中的科学、技术与工程的训练方法与管理技巧&#xff1b;上述方法和技巧的应用&#xff1b;计算机及其…

【氮化镓】GaN器件在航天器高可靠正向转换器中应用

文章是发表在《IEEE Journal of Emerging and Selected Topics in Power Electronics》2022年10月第10卷第5期上的一篇关于GaN(氮化镓)器件在航天器高可靠性正向转换器中应用的研究。文章的作者是匹兹堡大学电气与计算机工程系的Aidan Phillips, Thomas Cook和Brandon M. Gra…

【C语言视角】数据结构之~二叉树

前言&#xff1a;总所周知~数据结构的二叉树对于初学者来说是一个十分难理解的知识点。接下来&#xff0c;请阅读本人对二叉树拙劣的理解~ 目录 1.二叉树概念及结构 和性质 二叉树的结构 二叉树的存储结构 2.二叉树顺序结构 3.二叉树链式结构的实现 二叉树层序遍历 1.二叉树…

Flask路由的使用

Flask 是一个轻量级的 Python Web 框架&#xff0c;其简洁的设计使得构建 Web 应用变得轻而易举。其中&#xff0c;路由是 Flask 中至关重要的一部分&#xff0c;它定义了 URL 与视图函数之间的映射关系&#xff0c;决定了用户请求的处理方式。在本文中&#xff0c;我们将深入探…

服务运营 | 精选:用药难?用药贵?运筹学与统计学视角下的药物研发与管理

作者设计了一个多阶段博弈论模型来针对罕见病的不同补贴方案&#xff0c;分析政府、联盟、制药商和患者之间的相互作用。 制药商补贴为 α C \alpha C αC&#xff0c;其中 C C C是研发成本&#xff0c; α ∈ [ 0 , 1 ) \alpha \in [0,1) α∈[0,1)是政府总成本的比例。患者补…

ASP.NET淘宝店主交易管理系统的设计与实现

摘 要 淘宝店主交易管理系统主要采用了ASPACCESS的B/S设计模式&#xff0c;通过网络之间的数据交换来实现客户、商品、交易的管理和对客户、商品、交易统计工作&#xff0c;从而提高淘宝店主在管理网店过程中的工作效率和质量。 系统分为基本资料模块&#xff0c;统计资料模…

系统调用 int 86 的过程

该图借鉴与 Linux系统调用全过程详解-高性能服务器开发&#xff0c;向作者致敬。

Vue 之 在当前页面的实现分页效果

目录 场景实现 场景 假设&#xff0c;我们现在有这么一个需求&#xff1a; 上述图片的空白内容是活动的&#xff0c;由下面的两个按钮控制上一页、下一页&#xff1b;我们应该可以怎么去实现&#xff1f; 实现 思路&#xff1a; 其实这个问题&#xff0c;我们仿照其他的UI框…

关于远程桌面与3389端口的深度解析

当我们谈论远程桌面和3389端口时&#xff0c;我们实际上是在探讨Windows操作系统的一个核心功能&#xff0c;该功能允许用户通过网络从任何地点远程控制和管理计算机。而3389端口&#xff0c;正是这一功能所依赖的通信端口。 一、远程桌面的工作原理 远程桌面协议&#xff08;R…