使用Spring Boot实现分布式事务
使用Spring Boot实现分布式事务
大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!
在微服务架构中,分布式事务是一个重要的概念,它用于确保在分布式系统中各个服务之间的数据一致性。分布式事务的实现相对复杂,因为它需要跨越多个服务、数据库或消息队列来维护数据的一致性。本文将详细介绍如何使用Spring Boot实现分布式事务,重点介绍如何使用Spring Cloud和Seata框架来管理分布式事务。
一、分布式事务的基本概念
分布式事务是指在多个不同的数据库或服务之间执行的事务操作,这些操作需要保证一致性和完整性。分布式事务通常通过两阶段提交(2PC)、三阶段提交(3PC)或TCC(Try-Confirm/Cancel)等协议来实现。
二、Seata简介
Seata(Simple Extensible Autonomous Transaction Architecture)是阿里巴巴开源的一款分布式事务解决方案,提供了高效且易用的分布式事务服务。Seata支持AT、TCC、SAGA和XA等多种事务模式。
三、环境准备
JDK 8或以上版本
Maven 3或以上版本
MySQL数据库
Seata Server
四、创建Spring Boot项目
首先,我们使用Spring Initializr创建一个新的Spring Boot项目,并添加必要的依赖。
打开 Spring Initializr
输入项目信息:
Group: cn.juwatech
Artifact: spring-boot-seata
添加依赖:
Spring Web
Spring Data JPA
MySQL Driver
Seata Spring Boot Starter
点击“Generate”按钮生成项目并下载,然后解压项目文件。
- 在
src/main/resources
目录下创建application.yml
配置文件,添加以下内容:
server: port: 8080 spring: application: name: spring-boot-seata datasource: url: jdbc:mysql://localhost:3306/seata_example username: root password: password driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true seata: enabled: true application-id: spring-boot-seata tx-service-group: my_test_tx_group
- 在
src/main/resources
目录下创建seata.conf
配置文件,添加以下内容:
transport { type = "TCP" server = "NIO" heartbeat = "true" serialization = "seata" compressor = "none" } service { vgroupMapping.my_test_tx_group = "default" enableDegrade = false disableGlobalTransaction = false } client { rm { asyncCommitBufferLimit = 10000 lock { retryTimes = 30 retryInterval = 10 } reportRetryCount = 5 tableMetaCheckEnable = false } tm { commitRetryCount = 5 rollbackRetryCount = 5 } undo { dataValidation = true logSerialization = "jackson" onlyCareUpdateColumns = true } } support { spring { datasource-autoproxy = false } }
六、编写业务逻辑
- 创建实体类
Order
和Account
:package cn.juwatech.seata.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String userId; private String productId; private Integer count; private Double money; // getters and setters }
package cn.juwatech.seata.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Account { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String userId; private Double balance; // getters and setters }
- 创建
OrderRepository
和AccountRepository
:package cn.juwatech.seata.repository; import cn.juwatech.seata.entity.Order; import org.springframework.data.jpa.repository.JpaRepository; public interface OrderRepository extends JpaRepository<Order, Long> { }
package cn.juwatech.seata.repository; import cn.juwatech.seata.entity.Account; import org.springframework.data.jpa.repository.JpaRepository; public interface AccountRepository extends JpaRepository<Account, Long> { Account findByUserId(String userId); }
- 创建服务类
OrderService
和AccountService
:package cn.juwatech.seata.service; import cn.juwatech.seata.entity.Order; import cn.juwatech.seata.repository.OrderRepository; import io.seata.spring.annotation.GlobalTransactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class OrderService { @Autowired private OrderRepository orderRepository; @GlobalTransactional(name = "my_test_tx_group", rollbackFor = Exception.class) public void createOrder(Order order) { orderRepository.save(order); } }
package cn.juwatech.seata.service; import cn.juwatech.seata.entity.Account; import cn.juwatech.seata.repository.AccountRepository; import io.seata.spring.annotation.GlobalTransactional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class AccountService { @Autowired private AccountRepository accountRepository; @GlobalTransactional(name = "my_test_tx_group", rollbackFor = Exception.class) public void decreaseBalance(String userId, double amount) { Account account = accountRepository.findByUserId(userId); if (account != null && account.getBalance() >= amount) { account.setBalance(account.getBalance() - amount); accountRepository.save(account); } else { throw new RuntimeException("Insufficient balance"); } } }
创建控制器
OrderController
package cn.juwatech.seata.controller; import cn.juwatech.seata.entity.Order; import cn.juwatech.seata.service.AccountService; import cn.juwatech.seata.service.OrderService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/orders") public class OrderController { @Autowired private OrderService orderService; @Autowired private AccountService accountService; @PostMapping("/create") public String createOrder(@RequestBody Order order) { orderService.createOrder(order); accountService.decreaseBalance(order.getUserId(), order.getMoney()); return "Order created successfully"; } }
七、运行并验证
启动 Spring Boot 应用程序,并验证分布式事务功能。
运行 SpringBootSeataApplication 类,启动 Spring Boot 应用程序。
使用 Postman 或其他工具发送 POST 请求到 http://localhost:8080/orders/create,请求体为{ "userId": "1", "productId": "P1001", "count": 2, "money": 200.00 }
- 检查 MySQL 数据库,验证订单和账户信息是否正确更新。
通过以上步骤,我们成功地将 Spring Boot 应用与 Seata 集成,实现了分布式事务管理。Seata 提供了强大的分布式事务管理功能,使得在微服务架构中实现数据一致性变得更加容易和高效。
- 创建服务类
- 创建
原文链接:https://blog.csdn.net/java666668888/article/details/140401681