使用Seata分布式事务的前提条件

注意:数据库表的主键问题!!!!!如果要使用seata,那么对应的表必须要有主键存在。

1.引入依赖

  <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <version>2.0.0.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>io.seata</groupId>
                    <artifactId>seata-all</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.0.0</version>
        </dependency>

配置文件:
在这里插入图片描述1. registry.conf:配置注册中心和配置中心,默认是file。
2. file.conf:seata工作规则信息
3. DataSourceConfig:配置代理数据源实现分支事务,如果没有注入,事务无法成功回滚

registry.conf(注册中心和配置中心在一个文件中)

文件包含两部分配置:

  1. 注册中心
  2. 配置中心

注册中心:

registry { # 注册中心配置
  # 可选项:file 、nacos 、eureka、redis、zk
  type = "file" # 指定nacos注册中心,默认是file。

  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = "public"
    cluster = "default"
  }
  eureka {
    serviceUrl = "http://localhost:1001/eureka"
    application = "default"
    weight = "1"
  }
  redis {
    serverAddr = "localhost:6381"
    db = "0"
  }
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
  }
  file {
    name = "file.conf"
  }
}

配置中心

config { # 配置中心
  # 可选项:file、nacos 、apollo、zk
  type = "file" # 指向file配置中心,也可以指向nacos等其他注册中心

  nacos {
    serverAddr = "localhost"
    namespace = "public"
    cluster = "default"
  }
  apollo {
    app.id = "fescar-server"
    apollo.meta = "http://192.168.1.204:8801"
  }
  zk {
    serverAddr = "127.0.0.1:2181"
    session.timeout = 6000
    connect.timeout = 2000
  }
  file {
    name = "file.conf"   # 通过file.conf配置seata参数,指向第二个配置文件
  }
}

file.conf

从下面开始到数据库配置信息都在file.conf文件中

该文件的命名取决于registry.conf配置中心的配置

由于registry.conf中配置的是

也就是说:file.conf文件名取决于registry的配置中心配置,如果registry配置的配置中心不是file,可以没有改文件。例如:如果配置中心是nacos,这是file.conf文件就不需要了,把file.conf文件内容交给nacos就可

网络传输配置:

transport {
  # tcp udt unix-domain-socket
  type = "TCP"
  #NIO NATIVE
  server = "NIO"
  #enable heartbeat
  heartbeat = true
  #thread factory for netty
  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"
    # netty boss thread size,will not be used for UDT
    boss-thread-size = 1
    #auto default pin or 8
    worker-thread-size = 8
  }
}

事务日志存储配置:该部分内容参照account-service中的file.conf配置

store {
  ## store mode: file、db
  mode = "file"  # 存储方式file、db

  ## file store
  file {
    dir = "sessionStore"

    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    max-branch-session-size = 16384
    # globe session size , if exceeded throws exceptions
    max-global-session-size = 512
    # file buffer size , if exceeded allocate new buffer
    file-write-buffer-cache-size = 16384
    # when recover batch read size
    session.reload.read_size = 100
    # async, sync
    flush-disk-mode = async
  }

  ## database store
  db {
    driver_class = ""
    url = ""
    user = ""
    password = ""
  }
}

当前微服务在seata服务器中注册的信息配置:

${spring.applicaiton.name}是你的服务名
default.grouplist = "127.0.0.1:8091"*#seata-server服务器地址,默认是8091

service {
  #vgroup->rgroup
  #必须和服务名一致:${spring.applicaiton.name}
  vgroup_mapping.${spring.application.name}-fescar-service-group = "default"
  #only support single node
  default.grouplist = "127.0.0.1:8091"*#seata-server服务器地址,默认是8091
  #degrade current not support
  enableDegrade = false
  #disable
  disable = false
}

客户端相关工作的机制

undo_log表在每个库中都存在

client {
  rm {
    async.commit.buffer.limit = 10000
    lock {
      retry.internal = 10
      retry.times = 30
      retry.policy.branch-rollback-on-conflict = true
    }
    report.retry.count = 5
    table.meta.check.enable = false
    report.success.enable = true
  }
  tm {
    commit.retry.count = 5
    rollback.retry.count = 5
  }
  undo {
    data.validation = true
    log.serialization = "jackson"
    log.table = "undo_log"
  }
  log {
    exceptionRate = 100
  }
  support {
    # auto proxy the DataSource bean
    spring.datasource.autoproxy = false
  }

}

每个数据库都要有一张undo_log日志表,sql如下:

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  `ext` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

在这里插入图片描述

java的DataSourceConfig配置

每一个微服务原来自己的数据源都必须使用DataSourceProxy代理,这样seata才能掌控所有事务。

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    /**
     * 需要将 DataSourceProxy 设置为主数据源,否则事务无法回滚
     *
     * @param druidDataSource The DruidDataSource
     * @return The default datasource
     */
    @Primary
    @Bean("dataSource")
    public DataSource dataSource(DruidDataSource druidDataSource) {
        return new DataSourceProxy(druidDataSource);
    }
}
发布了126 篇原创文章 · 获赞 6 · 访问量 3727

猜你喜欢

转载自blog.csdn.net/qq_40244391/article/details/104199682