分布式事务具体实现seata

1.seata是什么?

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

2.本文中主要讲解seata的AT事务模式,参考文档,为官方文档,这里不讲解原理,有兴趣自己去看

https://seata.io/zh-cn/docs/overview/what-is-seata.html

3.下载和安装seata

    3.1下载地址

        https://github.com/seata/seata/releases

    3.2按照图片下载对应的版本,我这里下载windows版的

分布式事务具体实现seata

 如果是linux,解压命令是ar -xvzf xxx.tar.gz

3.3更改配置文件,解压文件之后可以在seata目录的conf目录下看到两个文件

分布式事务具体实现seata

3.4更改file.conf文件

    3. 4.1 更改store里的mode为db

分布式事务具体实现seata

  3.4.2更改db里的数据库连接参数,讲下面的用户名和密码更换为自己的用户名和密码

分布式事务具体实现seata

 如果数据库是mysql8以上的,按以下方式更改

url更改为

jdbc:mysql://localhost:3306/seata?characterEncoding=utf8&useSSL=false&serverTimezone = GMT

数据库驱动driverClassName 更改为

com.mysql.cj.jdbc.Driver

分布式事务具体实现seata

其次,如果是seata的低版本还要将mysql的驱动包替换

分布式事务具体实现seata

将这个包替换到lib目录下

分布式事务具体实现seata

3.5更改registry.conf配置文件

分布式事务具体实现seata

 

3.6 1.0以后的版本去到以下网址下载配置文件

https://github.com/seata/seata/tree/develop/script/config-center

  下载以下几个配置文件,config.txtnacos-config.shnacos-config.py

分布式事务具体实现seata

 其中nacos的点击nacos进去下载分布式事务具体实现seata

然后更改配置config.txt里的配置,主要是数据库的四项

分布式事务具体实现seata还有事务分组的配置,其中fsp_tx_group可以随便写,但是在项目中需要填一致分布式事务具体实现seata 

 然后修改nacos-config.sh配置,将红圈中的修改为绝对路径,当然是windows下才这样,linux不需要

分布式事务具体实现seata

 

分布式事务具体实现seata

 最后启动nacos,打开git的 Git Bash Here执行sh nacos-config.sh命令,将配置加载进nacos

3.7进入数据库,创建一个seata的数据库,执行以下连接里的sql

https://github.com/seata/seata/tree/develop/script/server/db

分布式事务具体实现seata

会得到以下三张表,走到这里基本上环境算是搭建好了

分布式事务具体实现seata

 上一个简单的业务让大家用一下

新建三个工程,分别是订单(seata-order-service2001),仓储(seata-storage-service2002),账户(seata-account-service2003)

导入以下主要的pom依赖

<!--seata-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>seata-all</artifactId>
            <groupId>io.seata</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.4.1</version>
</dependency>

上面的版本换成自己下载的版本号

将file.conf和registry.conf放入类路径下

修改application.yml文件,在以下位置填上之前配置中填写的分组名称分布式事务具体实现seata

 编写代码,这里dao什么sql我就不贴了,主要看主业务逻辑

在订单创建的业务代码上加上一个注解

@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class)

就可以解决分布式事务问题,代码如下,其中name可填可不填,最好填上唯一标识,方便查找问题

/**
 * 创建订单->调用库存服务扣减库存->调用账户服务扣减账户余额->修改订单状态
 * 简单说:下订单->扣库存->减余额->改状态
 */
@Override
@GlobalTransactional(name = "fsp-create-order",rollbackFor = Exception.class)
public void create(Order order)
{
    log.info("----->开始新建订单");
    //1 新建订单
    orderDao.create(order);

    //2 扣减库存
    log.info("----->订单微服务开始调用库存,做扣减Count");
    storageService.decrease(order.getProductId(),order.getCount());
    log.info("----->订单微服务开始调用库存,做扣减end");

    //3 扣减账户
    log.info("----->订单微服务开始调用账户,做扣减Money");
    accountService.decrease(order.getUserId(),order.getMoney());
    log.info("----->订单微服务开始调用账户,做扣减end");

    //4 修改订单状态,从零到1,1代表已经完成
    log.info("----->修改订单状态开始");
    orderDao.update(order.getUserId(),0);
    log.info("----->修改订单状态结束");

    log.info("----->下订单结束了,O(∩_∩)O哈哈~");

}

库存调用的是接口,我这里用的openFeign

@FeignClient(value = "seata-storage-service")
public interface StorageService
{
    @PostMapping(value = "/storage/decrease")
    CommonResult decrease(@RequestParam("productId") Long productId, @RequestParam("count") Integer count);
}
还有账户的接口
@FeignClient(value = "seata-account-service")
public interface AccountService
{
    @PostMapping(value = "/account/decrease")
    CommonResult decrease(@RequestParam("userId") Long userId, @RequestParam("money") BigDecimal money);
}

调用的其他业务逻辑我就不贴了,到这个程度,大家应该都会写,就是简单的一个项目,@GlobalTransactional注解只需要加在事务发起者上,其他的都不需要加注解

上一篇:seata源码解析:seata-server启动时都做了哪些操作?


下一篇:分布式事务——seata简单使用