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

相关文章
|
3月前
|
Cloud Native Java Nacos
微服务时代的新宠儿!Spring Cloud Nacos实战指南,带你玩转服务发现与配置管理,拥抱云原生潮流!
【8月更文挑战第29天】Spring Cloud Nacos作为微服务架构中的新兴之星,凭借其轻量、高效的特点,迅速成为服务发现、配置管理和治理的首选方案。Nacos(命名和配置服务)由阿里巴巴开源,为云原生应用提供了动态服务发现及配置管理等功能,简化了服务间的调用与依赖管理。本文将指导你通过五个步骤在Spring Boot项目中集成Nacos,实现服务注册、发现及配置动态管理,从而轻松搭建出高效的微服务环境。
261 0
|
1月前
|
JSON SpringCloudAlibaba Java
Springcloud Alibaba + jdk17+nacos 项目实践
本文基于 `Springcloud Alibaba + JDK17 + Nacos2.x` 介绍了一个微服务项目的搭建过程,包括项目依赖、配置文件、开发实践中的新特性(如文本块、NPE增强、模式匹配)以及常见的问题和解决方案。通过本文,读者可以了解如何高效地搭建和开发微服务项目,并解决一些常见的开发难题。项目代码已上传至 Gitee,欢迎交流学习。
125 1
Springcloud Alibaba + jdk17+nacos 项目实践
|
30天前
|
人工智能 文字识别 Java
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
尼恩,一位拥有20年架构经验的老架构师,通过其深厚的架构功力,成功指导了一位9年经验的网易工程师转型为大模型架构师,薪资逆涨50%,年薪近80W。尼恩的指导不仅帮助这位工程师在一年内成为大模型架构师,还让他管理起了10人团队,产品成功应用于多家大中型企业。尼恩因此决定编写《LLM大模型学习圣经》系列,帮助更多人掌握大模型架构,实现职业跃迁。该系列包括《从0到1吃透Transformer技术底座》、《从0到1精通RAG架构》等,旨在系统化、体系化地讲解大模型技术,助力读者实现“offer直提”。此外,尼恩还分享了多个技术圣经,如《NIO圣经》、《Docker圣经》等,帮助读者深入理解核心技术。
SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?
|
30天前
|
负载均衡 算法 Java
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
40岁老架构师尼恩分享了关于SpringCloud核心组件的底层原理,特别是针对蚂蚁集团面试中常见的面试题进行了详细解析。内容涵盖了Nacos注册中心的AP/CP模式、Distro和Raft分布式协议、Sentinel的高可用组件、负载均衡组件的实现原理等。尼恩强调了系统化学习的重要性,推荐了《尼恩Java面试宝典PDF》等资料,帮助读者更好地准备面试,提高技术实力,最终实现“offer自由”。更多技术资料和指导,可关注公众号【技术自由圈】获取。
蚂蚁面试:Nacos、Sentinel了解吗?Springcloud 核心底层原理,你知道多少?
|
2月前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
2月前
|
SQL NoSQL 数据库
SpringCloud基础6——分布式事务,Seata
分布式事务、ACID原则、CAP定理、Seata、Seata的四种分布式方案:XA、AT、TCC、SAGA模式
SpringCloud基础6——分布式事务,Seata
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
2月前
|
消息中间件 Java 对象存储
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
50 2
|
1月前
|
负载均衡 算法 Nacos
SpringCloud 微服务nacos和eureka
SpringCloud 微服务nacos和eureka
59 0
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡