SpringCloud系列——分布式事务seata整合实战

Posted 北溟溟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud系列——分布式事务seata整合实战相关的知识,希望对你有一定的参考价值。

前言

在微服务项目中,分布式事务也是我们需要处理的问题之一。在涉及到服务间相互调用的过程中,例如A服务调用B服务,在A服务调用B服务成功之后,A服务出现异常导致事务回滚,这个时候B服务已经调用成功,B服务的事务是不会回滚的,那么毫无疑问B服务中执行的增删改操作会导致最终B服务数据库中出现脏数据,从而导致业务出错。上述服务间相互调用出现的问题就是我们要使用分布式事务的原因,我们要保证A服务在出现异常回滚的时候,利用分布式事务的补偿机制使B服务的事务在异常情况下也可以回滚。本节我们主要使用alibaba开源的分布式事务组件seata实现分布式事务的控制,Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。(官方说明,请参考官方文档地址https://seata.io/zh-cn/docs/overview/what-is-seata.html)另外使用Seata处理分布式事务要慎重,仅适合在并发量不是很高的场景中,在高并发服务中,我们一般使用MQ消息中间键的方案实现分布式事务处理。

正文

  • Seata安装

①使用docker方式安装Seata服务

命令:docker run --name seata-server -p 8091:8091 --restart=always -d seataio/seata-server:latest

  •  整合Seata

①manager和member微服务pom中引入seata依赖

<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
	<version>2.2.5.RELEASE</version>
</dependency>

ps:注意引入的seata版本要和Seata服务版本一致

②配置seata

#====================================Seata Config===============================================
seata:
  enabled: true
  application-id: ${spring.application.name}
  tx-service-group: ${spring.application.name}-seata-service-group # 事务群组(可以每个应用独立取名,也可以使用相同的名字)
  client:
    rm-report-success-enable: true
    rm-table-meta-check-enable: false # 自动刷新缓存中的表结构(默认false)
    rm-report-retry-count: 5 # 一阶段结果上报TC重试次数(默认5)
    rm-async-commit-buffer-limit: 10000 # 异步提交缓存队列长度(默认10000)
    rm:
      lock:
        lock-retry-internal: 10 # 校验或占用全局锁重试间隔(默认10ms)
        lock-retry-times: 30 # 校验或占用全局锁重试次数(默认30)
        lock-retry-policy-branch-rollback-on-conflict: true # 分支事务与其它全局回滚事务冲突时锁策略(优先释放本地锁让回滚成功)
    tm-commit-retry-count: 3 # 一阶段全局提交结果上报TC重试次数(默认1次,建议大于1)
    tm-rollback-retry-count: 3 # 一阶段全局回滚结果上报TC重试次数(默认1次,建议大于1)
    undo:
      undo-data-validation: true # 二阶段回滚镜像校验(默认true开启)
      undo-log-serialization: jackson # undo序列化方式(默认jackson)
      undo-log-table: undo_log  # 自定义undo表名(默认undo_log)
    log:
      exceptionRate: 100 # 日志异常输出概率(默认100)
    support:
      spring:
        datasource-autoproxy: true
  service:
    enable-degrade: false # 降级开关
    disable-global-transaction: false # 禁用全局事务(默认false)
    grouplist:
      default: 192.168.23.134:8091
    vgroup-mapping:
      aiyundun-manager-seata-service-group: default # TC 集群(必须与seata-server保持一致)
  transport:
    shutdown:
      wait: 3
    thread-factory:
      boss-thread-prefix: NettyBoss
      worker-thread-prefix: NettyServerNIOWorker
      server-executor-thread-prefix: NettyServerBizHandler
      share-boss-worker: false
      client-selector-thread-prefix: NettyClientSelector
      client-selector-thread-size: 1
      client-worker-thread-prefix: NettyClientWorkerThread
    type: TCP
    server: NIO
    heartbeat: true
    serialization: seata
    compressor: none
    enable-client-batch-send-request: true # 客户端事务消息请求是否批量合并发送(默认true)
  registry:
    file:
      name: file.conf
    type: file
  config:
    file:
      name: file.conf
    type: file

 

ps:seata的配置可以使用file、nacos、zk等方式,为了简便演示这里我们使用file方式,其它方式请参考官方文档。

③创建分布式事务表

说明:manager和member微服务的数据库中分别创建一个undo_log表,用于分布式事务的管理。

CREATE TABLE `undo_log`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(0) NOT NULL,
  `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(0) NOT NULL,
  `log_created` datetime(0) NOT NULL,
  `log_modified` datetime(0) NOT NULL,
  `ext` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = 'seata事务控制表' ROW_FORMAT = Dynamic;

④编写测试方法

说明:在A服务上加上全局事务注解@GlobalTransactional,A服务是一个保存数据的服务,B服务是通过openfeign远程保存数据的服务,这俩个服务可根据自身业务自行定义,验证当异常发生时B服务是否也会出现事务回滚。

⑤验证

A服务出现异常回滚

B服务也回滚

查看数据库,manager和member微服务都没有新增数据成功,说明分布式事务生效,实现了分布式事务的回滚。

结语

ok,关于seata分布式事务的实战到这里就结束了,我们下期见。。。

以上是关于SpringCloud系列——分布式事务seata整合实战的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud-2.0-周阳(24. 分布式事务 - Seata)

SpringCloud - Spring Cloud Alibaba 之 Seata分布式事务服务;Seata TC Server集群部署(二十二)

SpringCloud - Spring Cloud Alibaba 之 Seata分布式事务服务;TCC事务模式机制(二十三)

SpringCloud Alibaba Seata---处理分布式事务

SpringCloud Alibaba 使用Seata解决分布式事物

SpringCloud-Seata分布式事物