Seata源码(十九)AT和XA模式例子


铿然架构 | 作者 / 铿然一叶 这是 铿然架构 的第 109 篇原创文章


1. 安装Server

1.下载软件 github.com/seata/seata...

2.本地目录解压 D:\MyApp\seata\seataserver1.7.1

3.启动server seata-server.bat

注意:配置文件在D:\MyApp\seata\seataserver1.7.1\conf\application.yml,默认使用文件方式,不需要修改

2. 运行Demo

2.1 克隆代码到本地

github.com/seata/seata...

demo架构图:

2.2 打开Seata-xa的例子

注:XA和AT模式的demo是同一个,只需要修改下使用的数据库代理类。

2.3 创建数据库和用户

该例子只使用一个数据库。

sql 复制代码
CREATE DATABASE businessdb;
create user business@'%' IDENTIFIED BY 'business123';
GRANT ALL PRIVILEGES ON businessdb.* TO business@'%';

2.4 创建表

执行业务脚本:

AT模式undo log脚本:

r 复制代码
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=1 DEFAULT CHARSET=utf8;

2.5 修改数据库配置

修改每个module的数据库配置

2.6 修改代码使用AT模式

修改module下的xxxxxDataSourceConfiguration文件

2.7 启动各个module

注:每次启动bussiness-xa module都会初始化数据库里的数据。

3. 测试

发送HTTP请求:

http://127.0.0.1:8084/purchase?rollback=false&count=1

通过浏览器,curl命令,postman都可以。

参数说明:

参数 说明
rollback 是否回退,如果回退,代码中抛出异常触发回退操作
count 订单数量,扣减库存,如果不传入,默认每次是30

初始化库存总量为:100,账户余额为:1000。

3.1 测试场景

3.1.1 正常测试

订购数量小于库存,账户余额足够:

http://127.0.0.1:8084/purchase?rollback=false&count=1

3.1.2 账户余额不足

订购数量大于库存,所需购买金额大于账户余额:

http://127.0.0.1:8084/purchase?rollback=false&count=10000

3.1.3 手动触发回退

设置rollback为true:

http://127.0.0.1:8084/purchase?rollback=true&count=1

3.2 AT模式支持

1.添加maven依赖:

xml 复制代码
            <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>${seata.version}</version>
            </dependency>

2.业务入口增加GlobalTransactional注解

注:GlobalTransactional可加在类上或者方法上

typescript 复制代码
// BusinessService.java
    @GlobalTransactional
    public void purchase(String userId, String commodityCode, int orderCount, boolean rollback) {
        String xid = RootContext.getXID();
        LOGGER.info("New Transaction Begins: " + xid);

        String result = stockFeignClient.deduct(commodityCode, orderCount);

        if (!SUCCESS.equals(result)) {
            throw new RuntimeException("库存服务调用失败,事务回滚!");
        }

        result = orderFeignClient.create(userId, commodityCode, orderCount);

        if (!SUCCESS.equals(result)) {
            throw new RuntimeException("订单服务调用失败,事务回滚!");
        }

        if (rollback) {
            throw new RuntimeException("Force rollback ... ");
        }
    }

3.使用DataSourceProxy

kotlin 复制代码
package io.seata.sample;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSource;

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.jdbc.core.JdbcTemplate;

@Configuration
public class BusinessXADataSourceConfiguration {

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

    @Bean("dataSourceProxy")
    public DataSource dataSource(DruidDataSource druidDataSource) {
        // DataSourceProxy for AT mode
        return new DataSourceProxy(druidDataSource);

        // DataSourceProxyXA for XA mode
//        return new DataSourceProxyXA(druidDataSource);
    }

    @Bean("jdbcTemplate")
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

其他阅读:

萌新快速成长之路
如何编写软件设计文档
JAVA编程思想(一)通过依赖注入增加扩展性
JAVA编程思想(二)如何面向接口编程
JAVA编程思想(三)去掉别扭的if,自注册策略模式优雅满足开闭原则
JAVA编程思想(四)Builder模式经典范式以及和工厂模式如何选?
Java编程思想(七)使用组合和继承的场景
JAVA基础(一)简单、透彻理解内部类和静态内部类
JAVA基础(二)内存优化-使用Java引用做缓存
JAVA基础(三)ClassLoader实现热加载
JAVA基础(四)枚举(enum)和常量定义,工厂类使用对比
JAVA基础(五)函数式接口-复用,解耦之利刃

相关推荐
是小崔啊3 分钟前
开源轮子 - EasyExcel02(深入实践)
java·开源·excel
myNameGL35 分钟前
linux安装idea
java·ide·intellij-idea
青春男大36 分钟前
java栈--数据结构
java·开发语言·数据结构·学习·eclipse
HaiFan.1 小时前
SpringBoot 事务
java·数据库·spring boot·sql·mysql
我要学编程(ಥ_ಥ)1 小时前
一文详解“二叉树中的深搜“在算法中的应用
java·数据结构·算法·leetcode·深度优先
music0ant1 小时前
Idea 添加tomcat 并发布到tomcat
java·tomcat·intellij-idea
计算机徐师兄2 小时前
Java基于SSM框架的无中介租房系统小程序【附源码、文档】
java·微信小程序·小程序·无中介租房系统小程序·java无中介租房系统小程序·无中介租房微信小程序
源码哥_博纳软云2 小时前
JAVA智慧养老养老护理帮忙代办陪诊陪护小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
忒可君3 小时前
C# winform 报错:类型“System.Int32”的对象无法转换为类型“System.Int16”。
java·开发语言
斌斌_____3 小时前
Spring Boot 配置文件的加载顺序
java·spring boot·后端