当前位置:   article > 正文

若依集成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`);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 第二步:
    新建一个数据库: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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

直接复制后执行就行。

3.2.2 修改application.yml

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

server:
  port: 7091
 
spring:
  application:
    name: seata-server
 
logging:
  config: classpath:logback-spring.xml
  file:
    path: ${user.home}/logs/seata
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash
 
console:
  user:
    username: seata
    password: seata
 
seata:
  config:
    # support: nacos 、 consul 、 apollo 、 zk  、 etcd3
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: dev
      group: SEATA_GROUP
      username: nacos
      password: ncs-nacos
      data-id: seataServer.properties
    
  registry:
    # support: nacos 、 eureka 、 redis 、 zk  、 consul 、 etcd3 、 sofa
    type: nacos
    preferred-networks: 30.240.*
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      namespace: dev
      group: SEATA_GROUP
      username: nacos
      password: ncs-nacos
      cluster: 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: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

我们可以看到在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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131

我这里的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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117

我这里的数据库用的是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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

其他的不变,文件内容准备好了,那么刚才说要在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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

4.2 微服务配置

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

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

# seata配置
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: default_tx_group
  enable-auto-data-source-proxy: false
  # seata nacos注册中心配置
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr:  127.0.0.1:8848
      group: SEATA_GROUP
      namespace: dev
  # seata nacos配置中心配置
  config:
    type: nacos
    nacos:
      server-addr:  127.0.0.1:8848
      group: SEATA_GROUP
      namespace: dev
      data-id: seataServer.properties
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

可能有些小伙伴要奇怪了我这里没有写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":"看看能不能插入成功"
}'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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分布式事务的一些幺蛾子

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/813865
推荐阅读
相关标签
  

闽ICP备14008679号