Springcloud结合mybatis-plus与nacos实现分布式事务seata

简介: Springcloud结合mybatis-plus与nacos实现分布式事务seata

文章目录

简介

项目示例

seata配置启动

账户模块

mapper

启动账户

库存模块

mapper

启动账户模块

订单模块

依赖

yml配置

controller类

服务类

测试库存模块

获取商品

扣减库存

测试账户模块

获取用户

扣减账户

测试订单

不加事务模拟下单

不加事务模拟异常

加事务模拟异常

简介

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

项目示例

用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:

库存服务:对给定的商品扣除仓储数量。

订单服务:根据采购需求创建订单。

帐户服务:从用户帐户中扣除余额。

8e0b64b55b8c4e32a10dd302b60c6ccb.png

seata配置启动

#初始化seata 的nacos配置

cd conf

sh nacos-config.sh 127.0.0.1

#启动seata-server

cd bin

seata-server.bat -p 8091 -h 127.0.0.1 -m db

61be66431fa74132a66b092770ea5906.png

配置可以参考官方的配置。

账户模块

mapper

/**

*

*  Mapper 接口

*

*

* @author elite

* @since 2022-09-11

*/

@Mapper

public interface AccountMapper extends BaseMapper {

   /**

    * 更新账户余额

    * @param user_id

    * @param amt

    * @return

    */

   @Update("UPDATE seata_account.account SET  acc_money= acc_money - #{amt} WHERE user_id = #{user_id} and (acc_money - #{amt}) >= 0")

   boolean deductAcct(Integer user_id, BigDecimal amt);

}

启动账户

e08de4292fc942fa8ea0024073988d84.png

库存模块

mapper

/**

*

* 库存表 Mapper 接口

*

*

* @author elite

* @since 2022-09-11

*/

@Mapper

public interface StockMapper extends BaseMapper {

   @Update("UPDATE seata_stock.stock set stock_num = stock_num - #{product_num} WHERE product_id = #{product_id} and  (stock_num - #{product_num}) >= 0")

   boolean deuctStock(Integer product_id, Integer product_num);

}

启动账户模块

d0203907876c4b048224ac46fd593a5f.png

订单模块

依赖

 

 

      com.alibaba.cloud

      spring-cloud-alibaba-seata

      2.2.0.RELEASE

 

 

yml配置

server:

 port: 8087

spring:

 application:

   name: springcloud-seata-order

 ##nacos服务地址注册

 cloud:

   nacos:

     discovery:

       server-addr: 192.168.5.130:8848

       enabled: true

   alibaba:

     seata:

       tx-service-group: springcloud-seata-order

 #配置数据库

 datasource:

   type: com.alibaba.druid.pool.DruidDataSource

   url: jdbc:mysql://192.168.5.130:3306/seata_order

   driver-class-name: com.mysql.jdbc.Driver

   username: root

   password: 123456

   druid:

     # 初始化大小,最小,最大

     initialSize: 5

     minIdle: 5

     maxActive: 20

     # 配置获取连接等待超时的时间(毫秒)

     maxWait: 60000

     # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒

     timeBetweenEvictionRunsMillis: 60000

     # 配置有一个连接在连接池中的最小生存时间,单位是毫秒

     minEvictableIdleTimeMillis: 300000

     validationQuery: SELECT 1 FROM DUAL

     testWhileIdle: true

     testOnBorrow: false

     testOnReturn: false

     # 打开PSCache,指定每个连接上PSCache的大小

     poolPreparedStatements: true

     maxPoolPreparedStatementPerConnectionSize: 20

     # 配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙

     filters: stat, wall, log4j

     # 通过connectProperties属性来打开mergeSql功能,慢SQL记录

     connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

#mybatis日志

mybatis-plus:

 configuration:

   log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

 mapper-locations: classpath:mapper/*.xml

controller类

/**

* <p>

* 订单表 前端控制器

* </p>

*

* @author elite

* @since 2022-09-11

*/

@RestController

@RequestMapping("/springcloud/order")

public class OrderController {

   @Autowired

   IOrderService orderService;

   /**

    * 传入用户id 商品id下单

    * @param product_id

    * @param user_id

    * @return

    */

   @GetMapping("/createOrder/{product_id}/{user_id}/{product_num}")

   public R createOrder(@PathVariable("")Integer product_id,

                        @PathVariable("user_id") Integer user_id,

                        @PathVariable("product_num")Integer product_num){

        R r = orderService.createOrder(product_id,user_id,product_num);

       return r;

   }

}

服务类

 

/**

* <p>

* 订单表 服务实现类

* </p>

*

* @author elite

* @since 2022-09-06

*/

@Service

@Slf4j

public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

   @Autowired

   OrderMapper orderMapper;

   //库存服务

   @Autowired

   StockService stockService;

   //账户服务

   @Autowired

   AcctService acctService;

   /**

    * 下单服务

    * @param product_id

    * @param user_id

    * @return

    */

   @GlobalTransactional

   @Override

   public R createOrder(Integer product_id, Integer user_id,Integer product_num) {

       //库存服务:对给定的商品扣除仓储数量。

       Product product = stockService.getProductById(product_id);

       if (product == null){

           return R.fail(400,"商品信息为空,商品ID不能为空");

       }

       boolean deductSuccess = stockService.deductStock(product_id, product_num);

       if (!deductSuccess){

           return R.fail(400,"扣减库存失败!");

       }

       //验证用户

       User user = acctService.getUserByUseId(user_id);

       if (user == null){

           return R.fail(400,"传入的用户ID不存在");

       }

       //订单服务:根据采购需求创建订单。

       BigDecimal amt = (product.getProductPrice()).multiply(new BigDecimal(product_num  ));

       //订单信息

       Order order = new Order();

       order.setOrderNo(10);

       order.setProductId(product_id);

       order.setUserId(user.getUserId());

       order.setOrderNum(product_num);

       order.setOrderAmt(amt); //单价*数量

       order.setOrderStatus("下单");

       order.setPayStatus("支付成功");

       order.setCreateBy("牛奶糖");

       order.setUpdateBy("牛奶糖");

       orderMapper.insert(order);

       //模拟异常

       //int i = 1/0;

       //帐户服务:从用户帐户中扣除余额。

       boolean deductAcctFlag = acctService.deductAcct(user_id, amt);

       if (!deductAcctFlag){

           return R.fail(400,"扣减账户失败!");

       }

       return R.ok(200,"下单成功!",order);

   }

}

测试库存模块

获取商品

93c9f49a5c53426a8733e51689a79fe7.png

扣减库存

4ff1892826de405ea1cf0b6d8243f586.png


执行的sql

==> Preparing: UPDATE seata_stock.stock set stock_num = stock_num - ? WHERE product_id = ? and (stock_num - ?) >= 0

aabc06ec857940548bad1a3f7c3738c0.png


测试账户模块

获取用户

111422df41f74fb7bafea5c933110be7.png

相关文章
|
1天前
|
Nacos 数据库
分布式事务解决方案Seata
分布式事务解决方案Seata
29 1
|
1天前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
201 0
|
1天前
|
Windows
Windows系统下安装分布式事务组件Seata
Windows系统下安装分布式事务组件Seata
|
1天前
|
SQL 容灾 数据库
分布式事务Seata
在分布式架构系统中,服务不止一个,一个完整的业务链路肯定也不止调用一个服务,此时每个服务都有自己的数据库增删改查,而每一个写操作对应一个本地事务。如果想要确保全部的业务状态一致,也就意味着需要所有的本地事务状态一致,这在我们之前的学习中肯定是不具备的,如何做到跨服务、跨数据源的事务一致性将是本章节的重点学习内容。
30 2
|
1天前
|
SpringCloudAlibaba Java Nacos
SpringCloud Alibaba微服务 -- Nacos使用以及注册中心和配置中心的应用(保姆级)
SpringCloud Alibaba微服务 -- Nacos使用以及注册中心和配置中心的应用(保姆级)
|
1天前
|
SQL 数据库 Windows
SpringCloud集成seata分布式事务控制
SpringCloud集成seata分布式事务控制
19 0
|
1天前
|
关系型数据库 MySQL 数据库
分布式事务Seata
分布式事务Seata
20 1
分布式事务Seata
|
1天前
|
NoSQL 关系型数据库 MySQL
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
472 1
|
1天前
|
敏捷开发 监控 前端开发
Spring+SpringMVC+Mybatis的分布式敏捷开发系统架构
Spring+SpringMVC+Mybatis的分布式敏捷开发系统架构
103 0
|
1天前
|
Nacos 数据库 Docker
nacos常见问题之docker部署的seata,成功注册到nacos运行报错如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
105 2

热门文章

最新文章