win10+springboot+dubbo+seataAT

seata详细中文文档见:   http://seata.io/zh-cn/docs/overview/what-is-seata.html

一.SeaTa在win10系统中安装调试

1. 下载seata客户端 : 下载地址: http://seata.io/zh-cn/blog/download.html,这里下载的是:binary格式的文件包,当前最新的版本1.4.2

2. 解压后修改配置文件. 这里注册中心是用的zk.所以只需要重点关注zk的配置项和seata所需的事务管理的数据库地址的配置.其他配置项.后续项目中可按需调整

  2.1registry.conf文件[seata服务注册配置]如下:

 

      registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "zk"
  
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  
  file {
    name = "file.conf"
  }
}

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

  zk {
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
    nodePath = "/seata/seata.properties"
  }

  file {
    name = "file.conf"
  }
}

 

 

  2.2  file.conf文件配置信息如下

  • transport {  
    # tcp, unix
    -domain-socket type = "TCP" #NIO, NATIVE server = "NIO" #enable heartbeat heartbeat = true # the client batch send request enable enableClientBatchSendRequest = false #thread factory for netty threadFactory { bossThreadPrefix = "NettyBoss" workerThreadPrefix = "NettyServerNIOWorker" serverExecutorThreadPrefix = "NettyServerBizHandler" shareBossWorker = false clientSelectorThreadPrefix = "NettyClientSelector" clientSelectorThreadSize = 1 clientWorkerThreadPrefix = "NettyClientWorkerThread" # netty boss thread size bossThreadSize = 1 #auto default pin or 8 workerThreadSize = "default" } shutdown { # when destroy server, wait seconds wait = 3 } serialization = "seata" compressor = "none" } store { ## store mode: file、db、redis mode = "db" ## database store property db { ## DataSource的实现类型, 可选择DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari)等类型 datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" ## if using mysql to store the data, recommend add rewriteBatchedStatements=true in jdbc connection param url = "jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true" user = "root" password = "root" minConn = 1 maxConn = 100 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 } } ## server configuration, only used in server side server { recovery { #schedule committing retry period in milliseconds committingRetryPeriod = 1000 #schedule asyn committing retry period in milliseconds asynCommittingRetryPeriod = 1000 #schedule rollbacking retry period in milliseconds rollbackingRetryPeriod = 1000 #schedule timeout retry period in milliseconds timeoutRetryPeriod = 1000 } undo { logSaveDays = 7 #schedule delete expired undo_log in milliseconds logDeletePeriod = 86400000 } #check auth enableCheckAuth = true #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent maxCommitRetryTimeout = "-1" maxRollbackRetryTimeout = "-1" rollbackRetryTimeoutUnlockEnable = false retryDeadThreshold = 130000 } ## metrics configuration, only used in server side metrics { enabled = false registryType = "compact" # multi exporters use comma divided exporterList = "prometheus" exporterPrometheusPort = 9898 } service { # 事务服务组,sp-user-seata-group可按需定义,但是要求这个和项目中的配置信息对的上 vgroupMapping.sp-user-seata-group = "default" #only support when registry.type=file, please don't set multiple addresses default.grouplist = "127.0.0.1:8091" #degrade, current not support enableDegrade = false #disable seata disableGlobalTransaction = false }

     

 

  2.3 事务管理相关表结构如下

 

-- 每个需要进行分布式事务管理的库中的undo_log[日志记录]表--AT模式只配置这个表即可
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,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

-- TCC模式下,可定义有个单独的库或者在现有库中配置事务相关表:
CREATE TABLE `branch_table` (
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(128) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `resource_group_id` varchar(32) DEFAULT NULL,
  `resource_id` varchar(256) DEFAULT NULL,
  `branch_type` varchar(8) DEFAULT NULL,
  `status` tinyint(4) DEFAULT NULL,
  `client_id` varchar(64) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime(6) DEFAULT NULL,
  `gmt_modified` datetime(6) DEFAULT NULL,
  PRIMARY KEY (`branch_id`),
  KEY `idx_xid` (`xid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `global_table` (
  `xid` varchar(128) NOT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `status` tinyint(4) NOT NULL,
  `application_id` varchar(32) DEFAULT NULL,
  `transaction_service_group` varchar(32) DEFAULT NULL,
  `transaction_name` varchar(128) DEFAULT NULL,
  `timeout` int(11) DEFAULT NULL,
  `begin_time` bigint(20) DEFAULT NULL,
  `application_data` varchar(2000) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`xid`),
  KEY `idx_gmt_modified_status` (`gmt_modified`,`status`),
  KEY `idx_transaction_id` (`transaction_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `lock_table` (
  `row_key` varchar(128) NOT NULL,
  `xid` varchar(128) DEFAULT NULL,
  `transaction_id` bigint(20) DEFAULT NULL,
  `branch_id` bigint(20) NOT NULL,
  `resource_id` varchar(256) DEFAULT NULL,
  `table_name` varchar(32) DEFAULT NULL,
  `pk` varchar(36) DEFAULT NULL,
  `gmt_create` datetime DEFAULT NULL,
  `gmt_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`row_key`),
  KEY `idx_branch_id` (`branch_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

 3.服务启动

   3.1.先启动本地zk服务.

        3.2 可在本地seata文件夹中黑窗口执行命令 :  .\bin\seata-server.bat .即可看到是否正常启动

4. 代码实现:

   4.1.导pom包:这里用的2.6.1版本的springboot ,  0.2.0的dubbo , 1.4.2的seata

<!-- https://mvnrepository.com/artifact/io.seata/seata-spring-boot-starter -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>${seata.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>seata-all</artifactId>
                    <groupId>io.seata</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.seata/seata-all -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>${seata.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- # seata zk连接主要依赖zkclient-->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.11</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

  4.2 .资源文件配置

# ************************** dataSource config start ****************************

spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/cloudtravel_consumer?useAffectedRows=true&serverTimezone=UTC&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.initialSize=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.max-active=20
spring.datasource.druid.max-wait=60000
spring.datasource.druid.time-between-eviction-runs-millis=60000
spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
spring.datasource.druid.test-while-idle=true
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.test-on-return=false
spring.datasource.druid.pool-prepared-statements=true
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
spring.datasource.druid.filter=stat
spring.datasource.druid.merge-sql=true
spring.datasource.druid.slow-sql-millis=5000
# 多数据源的情况下可指定对应的目录
mybatis.mapperLocations=classpath:mapper/*.xml

# ************************** dataSource config end ****************************

# ************************** seata config start ****************************
seata.enabled=true
seata.application-id=cloudtravel-consumer
seata.tx-service-group=sp-user-seata-group
seata.service.default.grouplist=127.0.0.1:8091
seata.service.vgroup-mapping.sp-user-seata-group=default
seata.enableAutoDataSourceProxy=false
seata.registry.type=zk
##seata.registry.file.name=registry.conf
# ************************** seata config end ****************************

  4.3.代码配置.我这里的druid数据库连接池是采用的手动配置

package com.cloudtravel.consumer.db;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = MainDataSourceConfig.BASE_PACKAGE , sqlSessionFactoryRef = "sqlSessionFactory")
public class MainDataSourceConfig {

    @Value("${mybatis.mapperLocations}")
    public String MAPPER_LOCATIONS;

    /** dao层接口所在的包 */
    public static final String BASE_PACKAGE = "com.cloudtravel.consumer.dao";
  /** 这里的配置项要和seata服务中的file.config文件中相应属性对的上 */
  @Value("${seata.application-id}")
  public String SEATA_APPLICATION_ID;
   /** 这里的配置项要和seata服务中的file.config文件中相应属性对的上 */
    @Value("${seata.tx-service-group}")
    public String TX_SERVICE_GROUP;

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

    //for seata
    @Bean("dataSourceProxy")
    public DataSourceProxy dataSourceProxy(@Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceProxy(dataSource);
    }

    @Bean("transactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSourceProxy") DataSourceProxy dataSourceProxy)throws Exception {
        final SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSourceProxy);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATIONS));
        return sqlSessionFactoryBean.getObject();
    }


    @Bean("globalTransactionScanner")
    public GlobalTransactionScanner globalTransactionScanner() {
        return new GlobalTransactionScanner(SEATA_APPLICATION_ID , TX_SERVICE_GROUP);
    }

}

     4.4. 代码中引入事务管理-AT模式.其实很简单,就是加个注解即可

@GlobalTransactional(name = "sp-user-seata-group" , rollbackFor = Exception.class)
    public String testAddUserAndSp() {
    ......正常的业务代码调用
    }

    4.5. 代码调试 : 

       1 找到 DefaultGlobalTransaction类,在begin / commit / rollback 三个方法处分别打个断点,打开数据库中的undo_log表,对应的业务数据表

    2. 进行业务调用 . 可通过断点一步步看到业务表中的数据生成 , undo_log表中快照数据生成 , ccommit时删除undo_log表中本次快照数据 . rollback时,根据xid[全局事务id]对业务数据进行补偿删除的过程

5.TCC

     .......待办

代码实战: github :  https://github.com/singleStudent/cloudtravel   gitee : https://gitee.com/everydayup/cloudtravel 

 

posted @ 2022-02-05 15:00  每天学习1点点  阅读(122)  评论(0编辑  收藏  举报