dubbo接入单机版seata AT模式

背景

想简单体验下AT模式,搞个简单的环境试一试,使用file模式,不接入nacos,seata也不接入mysql

安装seata

docker run -d --name seata-server -h 192.168.66.48 -p 8091:8091 -p 7091:7091 -e SEATA_IP=192.168.66.48  ca13393551e3

最后面的是seata的镜像,安装的是1.6.0版本,默认账号密码seata,启动即可使用
在这里插入图片描述
在这里插入图片描述

数据库部分

测试用的两个数据库,都要新增undo表

CREATE TABLE `undo_log` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `branch_id` bigint NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

程序部分

引用包

<dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.5.0</version>
        </dependency>

需要连接mysql的服务需要加注解开启数据源代理

@EnableAutoDataSourceProxy

@SpringBootApplication
@EnableDubbo
@EnableAutoDataSourceProxy
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
}

主服务使用@GlobalTransactional开启全局事务,timeout时间设置长一点,方便断点测试
在这里插入图片描述

服务上的seata配置

seata.enabled=true
seata.tx-service-group=sample-seata-test
seata.transport.type=TCP
seata.transport.server=NIO
# client和server通信心跳检测开关(默认为true)
seata.transport.heartbeat=true
seata.transport.enable-client-batch-send-request=true
seata.transport.thread-factory.boss-thread-prefix=NettyBoss
seata.transport.thread-factory.worker-thread-prefix=NettyServerNIOWorker
seata.transport.thread-factory.server-executor-thread-prefix=NettyServerBizHandler
seata.transport.thread-factory.share-boss-worker=false
seata.transport.thread-factory.client-selector-thread-prefix=NettyClientSelector
seata.transport.thread-factory.client-selector-thread-size=1
seata.transport.thread-factory.client-worker-thread-prefix=NettyClientWorkerThread
seata.transport.thread-factory.boss-thread-size=1

seata.transport.shutdown.wait=3
# client和server通信编解码方式
seata.transport.serialization=SEATA
seata.transport.compressor=none
# TC集群,需要和Seata-Server保持一致
seata.service.vgroupMapping.sample-seata-test=default
# 降级开关,默认为false,业务根据连续错误数自动降级,不走Seata事务
seata.service.enable-degrade=false
# 全局事务开关,默认为falsefalse为开启,true为关闭
seata.service.disable-global-transaction=false
# TC服务列表,也就是Seata服务端地址,只有当注册中心为file时使用
seata.service.grouplist.default=192.168.66.48:8091

其他的就是一个简单的dubbo调用,搞了两个更新,两个服务连了不同的mysql库
在这里插入图片描述

在这里插入图片描述

测试结果

正常流程

小demo起来后发现挺顺利,传参1跑异常回滚,两个表都没更新,传参其他的正常,两个表都更新
在这里插入图片描述

异常测试

在product服务更新时候,打上断点,然后修改user服务更新时候那行数据,把aaaa123改成其他的
在这里插入图片描述
在这里插入图片描述

我这里加了个更新接口单独更新了user服务的那个表,然后就报错了
user服务一直在重试归滚,后台也多了条全局锁,看日志是事务数据被污染,无法成功回滚,会一直重试,去user服务对应的mysql数据库中,删除undo_log的记录(删了两次),恢复正常
在这里插入图片描述
在这里插入图片描述
思考了一下我感觉,应该把updateUser也加入事务中
在这里插入图片描述
测试结果是现在获取锁超时,给更新后发起的更新操作失败了
在这里插入图片描述

总结

众所周知,seata的AT模式是最终一致性,测试看起来确实是,如果不对相关的操作加入事务,污染了事务数据,会导致事务回滚失败,一直回滚,在AT中就死锁了,这个应该是接入这个模式里面比较容易出现的一个坑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热一杯饼干

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值