使用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
配置文件,添加以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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
配置文件,添加以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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
:12345678910111213141516171819package
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
}
1234567891011121314151617package
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
:1234567package
cn.juwatech.seata.repository;
import
cn.juwatech.seata.entity.Order;
import
org.springframework.data.jpa.repository.JpaRepository;
public
interface
OrderRepository
extends
JpaRepository<Order, Long> {
}
12345678package
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
:12345678910111213141516171819package
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);
}
}
12345678910111213141516171819202122232425package
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
12345678910111213141516171819202122232425package
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,请求体为123456{
"userId"
:
"1"
,
"productId"
:
"P1001"
,
"count"
:
2
,
"money"
:
200.00
}
- 检查 MySQL 数据库,验证订单和账户信息是否正确更新。
通过以上步骤,我们成功地将 Spring Boot 应用与 Seata 集成,实现了分布式事务管理。Seata 提供了强大的分布式事务管理功能,使得在微服务架构中实现数据一致性变得更加容易和高效。
- 创建服务类
- 创建
原文链接:https://blog.csdn.net/java666668888/article/details/140401681
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2020-09-27 java中将文件夹里面的文件复制到指定的文件夹(java IO)
2020-09-27 JAVA中IO流详解