栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

分布式TC事务AT模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

分布式TC事务AT模式

分布式事务有以下解决方案:

  • XA
  • TCC
  • Seata 框架
  • AT 事务
  • SAGA
  • 可靠消息最终一致性
  • 最大努力通知
Seata

Seata 是一款开源一套一站式分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

Seata AT

Seata 的 AT 模式(Automatic Transaction)是一种无侵入的分布式事务解决方案

链接一:Seata AT具体工作机制

TC(Transaction Coordinator),事务协调器
因各服务之间无法相互感知事务是否执行成功,这时就需要一个专门的服务,来协调各个服务的运行状态。

TM(Transaction Manager,事务管理器),由 TM 向 TC 申请开启一个全局事务

RM(Resource Manager,资源管理器),RM 负责对分支事务(即微服务的本地事务)进行管理

链接二:Spring Cloud微服务添加 AT 分布式事务

Seata Server 就是 TC,直接从官方仓库下载启动即可,下载地址:https://github.com/seata/seata/releases

减小TC的压力,不存在集群,只能多创建几个事务组个管理各自的几个模块

Seata Server 配置

电脑内存不够的话seata-server.bat中 – 使用内存设置成256M

%JAVACMD% %JAVA_OPTS% -server -Xmx2048m -Xms2048m -Xmn1024m -Xss512k -XX:Sur......

Seata Server 的配置文件有两个:

  • seata/conf/registry.conf
  • seata/conf/file.conf
registry.conf

registrv.conf --向注册中心注册

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  # 这里选择 eureka 注册配置
  type = "eureka"

  nacos {
	......
  }

  # eureka的注册配置
  eureka {
    # 注册中心地址
    serviceUrl = "http://localhost:8761/eureka"
    # 向注册中心注册名字,注册的服务ID,默认default
    application = "seata-server"
    weight = "1"
  }
  
  redis {
	......
  }
  ......

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"

  nacos {
    serverAddr = "localhost"
    namespace = ""
    cluster = "default"
  }
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    # application = "default"
    # weight = "1"
  }
  redis {
    serverAddr = "localhost:6379"
    db = "0"
    password = ""
    cluster = "default"
    timeout = "0"
  }
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
    username = ""
    password = ""
  }
  consul {
    cluster = "default"
    serverAddr = "127.0.0.1:8500"
  }
  etcd3 {
    cluster = "default"
    serverAddr = "http://localhost:2379"
  }
  sofa {
    serverAddr = "127.0.0.1:9603"
    application = "default"
    region = "DEFAULT_ZONE"
    datacenter = "DefaultDataCenter"
    cluster = "default"
    group = "SEATA_GROUP"
    addressWaitTime = "3000"
  }
  file {
    name = "file.conf"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3、springCloudConfig
  type = "file"

  nacos {
    serverAddr = "localhost"
    namespace = ""
    group = "SEATA_GROUP"
  }
  consul {
    serverAddr = "127.0.0.1:8500"
  }
  apollo {
    app.id = "seata-server"
    apollo.meta = "http://192.168.1.204:8801"
    namespace = "application"
  }
  zk {
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
    username = ""
    password = ""
  }
  etcd3 {
    serverAddr = "http://localhost:2379"
  }
  file {
    name = "file.conf"
  }
}

file.conf

file.conf – 事务组对应使用的事务协调器
registry.conf 文件中配置eureka 注册中心,eureka服务的连接地址、注册的服务名
指定file.conf-- seata server运行过程中在库中记录日志

config {
  # file、nacos 、apollo、zk、consul、etcd3
  # 在这里选择使用本地文件来保存配置
  type = "file"


......

  etcd3 {
    serverAddr = "http://localhost:2379"
  }
  
  file {
    # 使用本地文件 在这里设置配置文件的文件名
    name = "file.conf"
  }
}

store {
  ## store mode: file、db、redis
  # 这里选择数据库存储
  mode = "db"

  ## file store property
  file {
  	......
  }

  # 数据库存储
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
    datasource = "druid"
    ## mysql/oracle/postgresql/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.jdbc.Driver"

	# 数据库连接配置
    url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8"
    user = "root"
    password = "root"
    minConn = 5
    maxConn = 30

	# 事务日志表表名设置
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"

    queryLimit = 100
    maxWait = 5000
  }

  ## redis store property
  redis {
  	......
  }
}

transport {
  # tcp udt unix-domain-socket
  type = "TCP"
  #NIO NATIVE
  server = "NIO"
  #enable heartbeat
  heartbeat = true
  # the client batch send request enable
  enableClientBatchSendRequest = true
  #thread factory for netty
  threadFactory {
    bossThreadPrefix = "NettyBoss"
    workerThreadPrefix = "NettyServerNIOWorker"
    serverExecutorThread-prefix = "NettyServerBizHandler"
    shareBossWorker = false
    clientSelectorThreadPrefix = "NettyClientSelector"
    clientSelectorThreadSize = 1
    clientWorkerThreadPrefix = "NettyClientWorkerThread"
    # netty boss thread size,will not be used for UDT
    bossThreadSize = 1
    #auto default pin or 8
    workerThreadSize = "default"
  }
  shutdown {
    # when destroy server, wait seconds
    wait = 3
  }
  serialization = "seata"
  compressor = "none"
}
service {
  #transaction service group mapping
  # order_tx_group 与 yml 中的 “tx-service-group: order_tx_group” 配置一致
  # “seata-server” 与 TC 服务器的注册名一致
  # 从eureka获取seata-server的地址,再向seata-server注册自己,设置group
  vgroupMapping.order_tx_group = "seata-server"
  #only support when registry.type=file, please don't set multiple addresses
  order_tx_group.grouplist = "127.0.0.1:8091"
  #degrade, current not support
  enableDegrade = false
  #disable seata
  disableGlobalTransaction = false
}

client {
  rm {
    asyncCommitBufferLimit = 10000
    lock {
      retryInterval = 10
      retryTimes = 30
      retryPolicyBranchRollbackonConflict = true
    }
    reportRetryCount = 5
    tablemetaCheckEnable = false
    reportSuccessEnable = false
  }
  tm {
    commitRetryCount = 5
    rollbackRetryCount = 5
  }
  undo {
    dataValidation = true
    logSerialization = "jackson"
    logTable = "undo_log"
  }
  log {
    exceptionRate = 100
  }
}

启动:双击seata/bin/seata-server.bat文件
或者在当前目录下CMD:seata-server.bat
报错:path、home环境
jdk新版不支持bat

业务模块中配置添加AT事物

file.conf

使用哪个协调器

service{
		VgroupMapping.事物组名="注册中心协调器名"
		}
或者
service{
		VgroupMapping.group="事物组名"
		VgroupMapping.tv="注册中心协调器名"
		}

application.yml

application.yml – 事务组命名
多个模块写一个事务组就行

spring:
  ......
  
  cloud:
    alibaba:
      seata: 
        tx-service-group: order_tx_group
     
   datasource:
	url: jdbc:mysql:/l/seata_order?useUnicode=true&driver-class-name: com.mysql.cj.jdbc.Driveruser
	name: root
	password: root
	jdbcUrl: ${spring. datasource.url}

......

在业务方法上,添加注解
@GlobalTransactional --用来启动全局事务,只在第一个模块(方法)添加。
@Transactional --控制本地事务

依赖:

   1.3.0
        2.0.0.RELEASE

        
          com.alibaba.cloud
          spring-cloud-alibaba-seata
          ${spring-cloud-alibaba-seata.version}
          
            
              seata-all
              io.seata
            
          
        
        
          io.seata
          seata-all
          ${seata.version}
        

错误:要么没配置,要么没配置正确

自己写数据源配置
通过创建数据源代理对象dataSourceProxy

配置类

import com.alibaba.druid.pool.DruidDataSource;
import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;

@Configuration
public class DSAutoConfiguration {
    // 创建原始数据源对象
     
    
   // @ConfigurationProperties把配置的参数(yml中的spring.datasource)注入HikariDataSource对象
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource();
        // return new DruidDataSource();
    }

    // 创建数据源代理对象,因为这里创建了两个同类型的对象,spring不知道选择谁,添加首先对象注解
    @Primary   // 首选对象
    @Bean
    public DataSource dataSourceProxy(DataSource ds) { //DataSource被代理的目标对象
        return new DataSourceProxy(ds);
    }

启动类中:
因为直接写了,就排除spring自己的默认配置类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

yml

第二阶段提交

失败的话
删除日志,回滚

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/292796.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号