分布式事务——dubbo集成seata示例

分布式事务——dubbo集成seata示例

1. 背景

在分布式事务框架选型中,seata一定会出现在评估范围内,这里通过dubbo项目集成seata tcc事务模式来体验seata的分布式事务。

seata版本1.5.2

2. 源码启动seata-server

1. 初始化配置到nacos

初始化seata的配置脚本在源码目录/seata/script/config-center/nacos,执行以下命令初始化配置到nacos,nacos要先开启

sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t default -u nacos -w nacos

有些属性添加报错,不用理会,不影响
在这里插入图片描述

按属性保存在nacos中的,而不是按文件,原因暂时不清楚。

这里日志存储在mysql中,所以要改对应的属性

store.mode=db
store.db.url=
store.db.user=
store.db.password=

mysql初始化脚本在seata/script/server/db/mysql.sql.

2. 修改server中的application.yml

seata/serverapplication.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: 405e877e-56ab-4755-8dd8-6541e1ee4845
      group: SEATA_GROUP
      username: nacos
      password: nacos
      #data-id: seataServer.properties
  # 注册seata-server
  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
      group: SEATA_GROUP
      namespace: 405e877e-56ab-4755-8dd8-6541e1ee4845
      cluster: default
      username: nacos
      password: nacos
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

3. 启动server

运行ServerApplication

如果遇到启动报如下错误:

A component required a bean of type 'io.seata.server.console.service.BranchSessionService' that could not be found.

是因为nacos配置中store.mode值DB大小问题,应该改成小写

3. TCC模式示例

技术组件:springboot、dubbo、zookeeper、nacos、seata

主体流程:创建订单,分别调用账户服务减余额,调用库存服务减库存

项目结构:
在这里插入图片描述

目标:创建订单成功后,调用账户服务和库存服务commit(),过程中有异常则调用服务rollback().

1. 接口定义

/**
 * 数字藏品账户服务
 * @author Tarzan写bug
 * @date 2022/12/08
 */
@LocalTCC
public interface DigitalAccountService {

    /**
     * 扣钱
     * @param id
     * @param money
     * @return
     */
    @TwoPhaseBusinessAction(name = "digitalAccountService", commitMethod = "commitDeductMoney", rollbackMethod = "rollbackDeductMoney")
    AccountDTO deductMoney(BusinessActionContext businessActionContext, Long id, BigDecimal money);

    AccountDTO commitDeductMoney(BusinessActionContext businessActionContext);

    AccountDTO rollbackDeductMoney(BusinessActionContext businessActionContext);
}
/**
 * 数字藏品库存
 * @author Tarzan写bug
 * @date 2022/12/08
 */
@LocalTCC
public interface DigitalInstockService {

    /**
     * 减库存
     * @param instockNum
     */
    @TwoPhaseBusinessAction(name = "digitalInstockService", commitMethod = "commitDeductInstock", rollbackMethod = "rollbackDeductInstock")
    void deductInstock(long instockNum);

    void commitDeductInstock(BusinessActionContext businessActionContext);

    void rollbackDeductInstock(BusinessActionContext businessActionContext);
}
/**
 * 数字藏品订单
 * @author Tarzan写bug
 * @date 2022/12/08
 */
public interface DigitalOrderService {

    /**
     * 创建订单
     * @param id
     */
    void createOrder(Long id);
}

在定义分支事务的时候,在接口类上标注@LocalTCC,定义3个方法prepare()commit()rollback(),在prepare()上标注@TwoPhaseBusinessAction,注解中的属性值name为bean的名称,commitMethod为提交方法的名称,rollbackMethod为回滚方法的名称。

2. 提供者端

添加seata的maven依赖

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

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
</dependency>

application.yml中添加seata client配置

seata:
  enabled: true
  # 应用名称
  application-id: digital-instock-provider
  # 事务组,要和服务端配置保持一致
  tx-service-group: default_tx_group
  client:
    rm-report-success-enable: true
    rm-table-meta-check-enable: false
    rm-report-retry-count: 5
    rm-async-commit-buffer-limit: 10000
    rm:
      lock:
        retry-interval: 10
        retry-times: 30
        retry-policy-branch-rollback-on-conflict: true
    tm:
      commit-retry-count: 3
      rollback-retry-count: 3
    undo:
      data-validation: true
      log-serialization: jackson
      log-table: undo_log
  service:
    # 跟服务端配置保持一致
    vgroup-mapping:
      default_tx_group: default
    enable-degrade: false
    disable-global-transaction: false
    grouplist:
      default: 127.0.0.1:8091
  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
  registry:
    type: nacos
    nacos:
      server-addr: localhost:8848
      namespace: 405e877e-56ab-4755-8dd8-6541e1ee4845
      group: SEATA_GROUP
      username: nacos
      password: nacos
  config:
    type: nacos
    nacos:
      server-addr: localhost:8848
      namespace: 405e877e-56ab-4755-8dd8-6541e1ee4845
      group: SEATA_GROUP
      username: nacos
      password: nacos
      # 貌似没什么用
      data-id: SEATA_CLIENT.properties

配置中主要关注seata.tx-service-groupseata.service.vgroup-mapping属性要跟服务端配置的保持一致,不然会报如下错误:

can not get cluster name in registry config 'service.vgroupMapping.oauth-seata-service-group', please make sure registry config correct

在事务发起者方法上添加@GlobalTransactional注解

@GlobalTransactional
@Override
public void createOrder(Long id) {
    LOGGER.info(this.getClass() + " createOrder()");
    accountService.deductMoney(null, id, new BigDecimal(100));
    instockService.deductInstock(2L);
}

3. 消费者端

dubbo消费者端不涉及seata.

4. 总结

代码收录在https://gitee.com/ouwenrts/seata-demo.git



世界那么大,感谢遇见,未来可期…

欢迎同频共振的那一部分人

作者公众号:Tarzan写bug

淘宝店:Tarzan小店 提供一元解决Java问题和其他方面的解决方案,欢迎咨询

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值