修改 conf 目录下的 file.conf 配置文件,主要修改自定义事务组名称,事务日志存储模式及数据库连接信息

transport {
    ...省略
}
service {
    #vgroup->rgroup
    vgroup_mapping.prex_tx_group = "default" #修改事务组名称为:prex_tx_group,和客户端自定义的名称对应
        #only support single node
        default.grouplist = "127.0.0.1:8091"
        #degrade current not support
        enableDegrade = false
        #disable
        disable = false
        #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
        max.commit.retry.timeout = "-1"
        max.rollback.retry.timeout = "-1"
}

## transaction log store
store {
    ## store mode: file、db
    mode = "db" #修改此处将事务信息存储到db数据库中

        ## database store
        db {
        ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
        datasource = "druid"
            ## mysql/oracle/h2/oceanbase etc.
            db-type = "mysql"
            driver-class-name = "com.mysql.jdbc.Driver"
            url = "jdbc:mysql://localhost:3306/seat" #修改数据库连接地址目前只支持mysql
            user = "root" #修改数据库用户名
            password = "root" #修改数据库密码
            min-conn = 1
            max-conn = 3
            global.table = "global_table"
            branch.table = "branch_table"
            lock-table = "lock_table"
            query-limit = 100
    }
}

说明:

· 存储事务日志可以使用 file 文件和 db 数据库两种方式

· 由于我们使用了 db 模式存储事务日志,所以我们需要创建一个 seat 数据库,建表 sql 在 seata-server 的/conf/db_store.sql 中

· 修改 conf 目录下的registry.conf配置文件,指明注册中心为 nacos,及修改 nacos 连接信息即可;

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

        nacos {
        serverAddr = "localhost:8848"
            namespace = ""
            cluster = "default"
    }
    ... 省略
}

配置完成后启动 Seata

启动 seata server 的脚本位于 bin 文件内,Linux/Mac 环境使用 seata-server.sh 脚本启动,Windows 环境使用 seata-server.bat 脚本启动。

Linux/Mac启动方式示例如下所示:

nohup sh seata-server.sh -p 8091 -h 127.0.0.1 -m db &> seata.log &

通过 nohup 命令让 seata server 在系统后台运行。

脚本参数:

· -p 指定启动 seata server 的端口号。

· -h 指定 seata server 所绑定的主机,这里配置要注意指定的主机 IP 要与业务服务内的配置文件保持一致,如:-h 192.168.1.10,业务服务配置文件内应该配置 192.168.1.10,即使在同一台主机上也要保持一致。

· -m 事务日志、事务执行信息存储的方式,目前支持 file(文件方式)、db(数据库方式,建表语句请查看 config/db_store.sql、config/db_undo_log.sql)

注意:db_undo_log.sql需要建在业务数据库中

注意:db_undo_log.sql需要建在业务数据库中

注意:db_undo_log.sql需要建在业务数据库中

· 修改 application.yml 文件,自定义事务组的名称

spring:
  cloud:
    alibaba:
      seata:
        tx-service-group: prex_tx_group #自定义事务组名称需要与seata-server中的对应

· 添加并修改 file.conf 配置文件,主要是修改自定义事务组名称(放在resource下)

service {
    #vgroup->rgroup
    vgroup_mapping.prex_tx_group = "default" #修改自定义事务组名称
        #only support single node
        default.grouplist = "127.0.0.1:8091"
        #degrade current not support
        enableDegrade = false
        #disable
        disable = false
        #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
        max.commit.retry.timeout = "-1"
        max.rollback.retry.timeout = "-1"
        disableGlobalTransaction = false
}

添加并修改 registry.conf 配置文件,主要是将注册中心改为 nacos(放在resource下)

registry {
    # file 、nacos 、eureka、redis、zk
    type = "nacos" #修改为nacos

        nacos {
        serverAddr = "localhost:8848" #修改为nacos的连接地址
            namespace = ""
            cluster = "default"
    }
}

· 在启动类中取消数据源的自动创建

@EnableDiscoveryClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@MapperScan("com.xd.example.seata.mapper")
public class NacosSeataAccountServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(NacosSeataAccountServerApplication.class, args);
    }

}

· 配置 MybatisPlus 使用 Seata 对数据源进行代理

MyBatisPlusConfig:

/**
 * @Classname MyBatisPlusConfig
 * @Description 配置MybatisPlus使用Seata对数据源进行代理
 * @Author Created by Lihaodong (alias:小东啊) im.lihaodong@gmail.com
 * @Date 2019-11-25 11:21
 * @Version 1.0
 */
@Configuration
public class MyBatisPlusConfig {

    @Value("${mybatis-plus.mapper-locations}")
    private String mapperLocations;

    /**
     * @param sqlSessionFactory SqlSessionFactory
     * @return SqlSessionTemplate
     */
    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    /**
     * 从配置文件获取属性构造datasource,注意前缀,这里用的是druid,根据自己情况配置,
     * 原生datasource前缀取"spring.datasource"
     *
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource hikariDataSource() {
        return new HikariDataSource();
    }

    /**
     * 构造datasource代理对象,替换原来的datasource
     *
     * @param hikariDataSource
     * @return
     */
    @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSourceProxy(DataSource hikariDataSource) {
        return new DataSourceProxy(hikariDataSource);
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSourceProxy);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        bean.setMapperLocations(resolver.getResources(mapperLocations));

        SqlSessionFactory factory = null;
        try {
            factory = bean.getObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return factory;
    }

    /**
     * MP 自带分页插件
     *
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }
}

开启事务

@GlobalTransactional(rollbackFor = Exception.class)

事务手动回滚

GlobalTransactionContext.reload(RootContext.getXID()).rollback();