🚀 前言:为什么事务管理如此重要?
在现代企业级应用开发中,数据一致性是系统的生命线。想象一个电商场景:用户下单购买商品,系统需要同时完成以下操作:
- 🛒 扣减库存:商品库存减1
- 💰 创建订单:生成订单记录
- 💳 扣款处理:用户账户余额扣减
- 📦 物流信息 :生成物流单号
如果其中任何一步失败,整个操作都应该回滚,否则就会出现"库存扣了但订单没创建"的严重数据不一致问题。Spring Boot的事务管理机制 正是为了解决这类问题而设计的。
🏗️ 一、Spring事务管理基础架构
1.1 事务管理核心组件架构

1.2 事务管理器体系结构
核心接口 :PlatformTransactionManager
java
public interface PlatformTransactionManager {
// 根据事务定义获取事务状态
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
// 提交事务
void commit(TransactionStatus status) throws TransactionException;
// 回滚事务
void rollback(TransactionStatus status) throws TransactionException;
}
主要实现类:
| 实现类 | 应用场景 | 特点 |
|---|---|---|
| DataSourceTransactionManager | JDBC/MyBatis | 单数据源事务管理 |
| JpaTransactionManager | JPA/Hibernate | JPA规范事务管理 |
| JtaTransactionManager | JTA分布式事务 | 支持多数据源XA事务 |
| HibernateTransactionManager | Hibernate原生 | Hibernate框架事务管理 |
🔍 二、事务传播机制深度解析
2.1 事务传播行为概览
事务传播行为定义了多个事务方法相互调用时,事务如何传播的行为。Spring提供了7种传播行为:

2.2 传播行为详细解析
2.2.1 REQUIRED(默认传播行为)
行为描述:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务。
java
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder(Order order) {
// 如果调用者有事务,加入;否则创建新事务
orderDao.save(order);
inventoryService.deductStock(order.getProductId(), order.getQuantity());
}
}
执行流程:

2.2.2 REQUIRES_NEW(独立新事务)
行为描述:总是创建新事务,如果当前存在事务,则将当前事务挂起。
typescript
@Service
public class LogService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveOperationLog(OperationLog log) {
// 无论调用者是否有事务,都创建新事务
logDao.save(log);
}
}
@Service
public class OrderService {
@Transactional
public void processOrder(Order order) {
try {
orderDao.save(order);
// 日志记录在新事务中执行,不受订单事务影响
logService.saveOperationLog(createLog(order));
} catch (Exception e) {
// 日志已经在新事务中提交,不会回滚
throw e;
}
}
}
执行流程:

2.2.3 NESTED(嵌套事务)
行为描述:如果当前存在事务,则在嵌套事务内执行;如果没有事务,则创建新事务。
java
@Service
public class PaymentService {
@Transactional
public void processPayment(Payment payment) {
try {
// 主事务逻辑
paymentDao.save(payment);
// 嵌套事务执行风险控制检查
riskControlService.checkRisk(payment);
} catch (RiskControlException e) {
// 嵌套事务回滚,但主事务可以继续
payment.setStatus(PaymentStatus.MANUAL_REVIEW);
paymentDao.update(payment);
}
}
}
@Service
public class RiskControlService {
@Transactional(propagation = Propagation.NESTED)
public void checkRisk(Payment payment) throws RiskControlException {
// 嵌套事务逻辑
riskRecordDao.save(createRiskRecord(payment));
if (isHighRisk(payment)) {
throw new RiskControlException("High risk detected");
}
}
}
嵌套事务原理:

🔄 三、嵌套事务原理与实战
3.1 嵌套事务底层实现机制
嵌套事务通过保存点 机制实现,它不是真正的事务嵌套,而是在同一物理事务中设置逻辑回滚点。 保存点机制:
ini
// JDBC中的保存点使用示例
Connection conn = dataSource.getConnection();
try {
conn.setAutoCommit(false);
// 主事务操作
Statement stmt1 = conn.createStatement();
stmt1.executeUpdate("INSERT INTO orders ...");
// 设置保存点
Savepoint savepoint = conn.setSavepoint("nested_start");
try {
// 嵌套事务操作
Statement stmt2 = conn.createStatement();
stmt2.executeUpdate("INSERT INTO risk_records ...");
// 嵌套事务提交(释放保存点)
conn.releaseSavepoint(savepoint);
} catch (SQLException e) {
// 嵌套事务回滚(回滚到保存点)
conn.rollback(savepoint);
}
// 主事务继续操作
Statement stmt3 = conn.createStatement();
stmt3.executeUpdate("UPDATE payments ...");
conn.commit();
} catch (SQLException e) {
conn.rollback();
}
3.2 嵌套事务实战场景
场景1:批量导入中的部分回滚
kotlin
@Service
public class ImportService {
@Transactional
public ImportResult batchImport(List<ImportData> dataList) {
ImportResult result = new ImportResult();
for (ImportData data : dataList) {
try {
// 每条记录在嵌套事务中处理
importSingleData(data);
result.incrementSuccess();
} catch (ImportException e) {
// 单条记录失败不影响其他记录
result.addFailure(data, e.getMessage());
}
}
return result;
}
@Transactional(propagation = Propagation.NESTED)
public void importSingleData(ImportData data) throws ImportException {
// 数据验证
if (!validateData(data)) {
throw new ImportException("数据验证失败");
}
// 保存数据
dataDao.save(data);
// 相关处理
relatedDataService.processRelated(data);
}
}
执行流程分析:

3.3 嵌套事务与REQUIRES_NEW的区别
| 特性 | NESTED | REQUIRES_NEW |
|---|---|---|
| 物理事务 | 同一个物理事务 | 独立的物理事务 |
| 回滚影响 | 只回滚到保存点 | 完全独立回滚 |
| 锁竞争 | 共享主事务锁 | 独立锁管理 |
| 性能开销 | 较小 | 较大 |
| 适用场景 | 逻辑嵌套回滚 | 完全独立业务 |
性能对比示例:
java
// 性能测试对比
@Service
public class PerformanceTestService {
// 嵌套事务性能测试
@Transactional
public void testNestedPerformance(int iterations) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
nestedOperation(i);
}
long endTime = System.currentTimeMillis();
System.out.println("NESTED耗时: " + (endTime - startTime) + "ms");
}
@Transactional(propagation = Propagation.NESTED)
public void nestedOperation(int index) {
// 简单数据库操作
testDao.save(new TestEntity("nested_" + index));
}
// REQUIRES_NEW性能测试
@Transactional
public void testRequiresNewPerformance(int iterations) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
requiresNewOperation(i);
}
long endTime = System.currentTimeMillis();
System.out.println("REQUIRES_NEW耗时: " + (endTime - startTime) + "ms");
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void requiresNewOperation(int index) {
// 相同的数据库操作
testDao.save(new TestEntity("requires_new_" + index));
}
}
⚠️ 四、事务失效场景深度复盘
4.1 事务失效场景分类

4.2 典型失效场景详解
4.2.1 方法访问修饰符问题
问题代码:
typescript
@Service
public class UserService {
// ❌ private方法,事务失效
@Transactional
private void updateUserPrivate(User user) {
userDao.update(user);
}
// ❌ protected方法,事务失效
@Transactional
protected void updateUserProtected(User user) {
userDao.update(user);
}
// ✅ public方法,事务正常
@Transactional
public void updateUserPublic(User user) {
userDao.update(user);
}
}
原因分析 : Spring的事务管理基于AOP代理机制 ,默认只能代理public方法。对于private、protected等方法,Spring AOP无法创建代理,因此事务失效。 解决方案:
typescript
@Service
public class UserService {
// 方法1:将方法改为public
@Transactional
public void updateUser(User user) {
userDao.update(user);
}
// 方法2:通过public方法调用
@Transactional
public void publicWrapperMethod(User user) {
updateUserInternal(user);
}
private void updateUserInternal(User user) {
userDao.update(user);
}
}
4.2.2 同类方法调用问题
问题代码:
typescript
@Service
public class OrderService {
@Transactional
public void createOrder(Order order) {
// ❌ 同类方法调用,事务失效
saveOrder(order);
updateInventory(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveOrder(Order order) {
orderDao.save(order);
}
@Transactional
public void updateInventory(Order order) {
inventoryDao.deductStock(order.getProductId(), order.getQuantity());
}
}
原因分析 : Spring AOP使用动态代理 ,当从外部调用方法时,会经过代理对象的事务拦截器。但同类内部方法调用 时,是直接调用原始对象的方法,绕过了代理对象,因此事务配置失效。 解决方案:
typescript
@Service
public class OrderService {
@Autowired
private OrderService self; // 注入自身代理对象
@Transactional
public void createOrder(Order order) {
// ✅ 通过代理对象调用
self.saveOrder(order);
self.updateInventory(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveOrder(Order order) {
orderDao.save(order);
}
@Transactional
public void updateInventory(Order order) {
inventoryDao.deductStock(order.getProductId(), order.getQuantity());
}
}
替代方案:
scss
@Service
public class OrderService {
@Transactional
public void createOrder(Order order) {
// ✅ 使用AopContext获取当前代理对象
((OrderService) AopContext.currentProxy()).saveOrder(order);
((OrderService) AopContext.currentProxy()).updateInventory(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveOrder(Order order) {
orderDao.save(order);
}
@Transactional
public void updateInventory(Order order) {
inventoryDao.deductStock(order.getProductId(), order.getQuantity());
}
}
4.2.3 异常处理机制问题
问题代码1:异常被吞掉:
typescript
@Service
public class PaymentService {
@Transactional
public void processPayment(Payment payment) {
try {
// 业务处理
paymentDao.save(payment);
accountService.deductAccount(payment);
} catch (Exception e) {
// ❌ 异常被捕获,事务不会回滚
log.error("支付处理失败", e);
}
}
}
原因分析 : Spring默认只在RuntimeException 和Error 时回滚事务。如果异常被捕获且未重新抛出,事务管理器认为方法执行成功,不会触发回滚。 解决方案:
typescript
@Service
public class PaymentService {
@Transactional
public void processPayment(Payment payment) {
try {
paymentDao.save(payment);
accountService.deductAccount(payment);
} catch (Exception e) {
// ✅ 记录日志后重新抛出异常
log.error("支付处理失败", e);
throw e; // 重新抛出异常,触发事务回滚
}
}
}
问题代码2:受检异常不回滚:
java
@Service
public class FileService {
@Transactional
public void processFile(String filePath) throws IOException {
// ❌ IOException是受检异常,默认不回滚
fileDao.save(new FileRecord(filePath));
processFileContent(filePath);
}
}
解决方案:
java
@Service
public class FileService {
// 方案1:指定回滚异常类型
@Transactional(rollbackFor = IOException.class)
public void processFile(String filePath) throws IOException {
fileDao.save(new FileRecord(filePath));
processFileContent(filePath);
}
// 方案2:指定所有异常都回滚
@Transactional(rollbackFor = Exception.class)
public void processFileV2(String filePath) throws IOException {
fileDao.save(new FileRecord(filePath));
processFileContent(filePath);
}
}
4.2.4 事务配置问题
问题代码:多数据源事务配置错误:
typescript
@Configuration
public class DataSourceConfig {
@Bean
@Primary
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
// ❌ 只配置了主数据源的事务管理器
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(primaryDataSource());
}
}
@Service
public class MultiDataSourceService {
@Autowired
private JdbcTemplate primaryJdbcTemplate;
@Autowired
private JdbcTemplate secondaryJdbcTemplate;
@Transactional // ❌ 只能管理主数据源事务
public void transferData() {
primaryJdbcTemplate.update("INSERT INTO primary_table ...");
secondaryJdbcTemplate.update("INSERT INTO secondary_table ..."); // 不在事务中
}
}
解决方案:
typescript
@Configuration
public class DataSourceConfig {
@Primary
@Bean
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean
public PlatformTransactionManager primaryTransactionManager() {
return new DataSourceTransactionManager(primaryDataSource());
}
@Bean
public PlatformTransactionManager secondaryTransactionManager() {
return new DataSourceTransactionManager(secondaryDataSource());
}
}
@Service
public class MultiDataSourceService {
@Autowired
@Qualifier("primaryJdbcTemplate")
private JdbcTemplate primaryJdbcTemplate;
@Autowired
@Qualifier("secondaryJdbcTemplate")
private JdbcTemplate secondaryJdbcTemplate;
// ✅ 指定具体的事务管理器
@Transactional("primaryTransactionManager")
public void transferPrimaryData() {
primaryJdbcTemplate.update("INSERT INTO primary_table ...");
}
@Transactional("secondaryTransactionManager")
public void transferSecondaryData() {
secondaryJdbcTemplate.update("INSERT INTO secondary_table ...");
}
// 对于跨数据源事务,需要使用JTA分布式事务
// 或者使用编程式事务管理
}
4.2.5 数据库引擎问题
问题代码:
sql
-- MySQL使用不支持事务的存储引擎
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
order_no VARCHAR(32),
amount DECIMAL(10,2)
) ENGINE=MyISAM; -- ❌ MyISAM不支持事务
解决方案:
sql
-- 使用支持事务的InnoDB引擎
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
order_no VARCHAR(32),
amount DECIMAL(10,2)
) ENGINE=InnoDB; -- ✅ InnoDB支持事务
不同数据库引擎事务支持对比:
| 数据库 | 引擎 | 事务支持 | 行级锁 | 外键约束 |
|---|---|---|---|---|
| MySQL | InnoDB | ✅ 支持 | ✅ 支持 | ✅ 支持 |
| MySQL | MyISAM | ❌ 不支持 | ❌ 不支持 | ❌ 不支持 |
| PostgreSQL | 默认 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
| Oracle | 默认 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
4.3 事务失效检测清单
开发前检查:

🌐 五、分布式事务处理
5.1 分布式事务场景分析
在微服务架构中,跨服务的事务管理是重大挑战。以下是典型场景:
5.2 分布式事务解决方案
5.2.1 本地消息表(最终一致性)
实现原理:
scss
@Service
public class OrderService {
@Autowired
private OrderDao orderDao;
@Autowired
private MessageLogDao messageLogDao;
@Autowired
private MessageProducer messageProducer;
@Transactional
public void createOrderWithMessage(Order order) {
// 1. 创建订单
orderDao.save(order);
// 2. 创建消息记录(本地事务)
MessageLog messageLog = new MessageLog();
messageLog.setOrderId(order.getId());
messageLog.setContent(JSON.toJSONString(order));
messageLog.setStatus(MessageStatus.SENDING);
messageLogDao.save(messageLog);
// 3. 事务提交后发送消息
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
try {
messageProducer.sendOrderMessage(order);
messageLog.setStatus(MessageStatus.SENT);
messageLogDao.update(messageLog);
} catch (Exception e) {
// 发送失败,后续定时任务重试
log.error("消息发送失败", e);
}
}
});
}
}
5.2.2 Seata AT模式(强一致性)
集成配置:
scss
// 订单服务
@Service
public class OrderService {
@Autowired
private OrderDao orderDao;
@Autowired
private InventoryServiceFeign inventoryService;
// ✅ Seata全局事务注解
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public void createOrder(Order order) {
// 本地事务操作
orderDao.save(order);
// 远程调用库存服务
InventoryDTO inventoryDTO = new InventoryDTO();
inventoryDTO.setProductId(order.getProductId());
inventoryDTO.setCount(order.getQuantity());
inventoryService.deductInventory(inventoryDTO);
// 远程调用支付服务
PaymentDTO paymentDTO = new PaymentDTO();
paymentDTO.setOrderId(order.getId());
paymentDTO.setAmount(order.getAmount());
paymentService.processPayment(paymentDTO);
}
}
// 库存服务
@Service
public class InventoryService {
@Autowired
private InventoryDao inventoryDao;
// ✅ Seata分支事务注解
@GlobalTransactional
public void deductInventory(InventoryDTO dto) {
// 检查库存
Inventory inventory = inventoryDao.findByProductId(dto.getProductId());
if (inventory.getCount() < dto.getCount()) {
throw new RuntimeException("库存不足");
}
// 扣减库存
inventory.setCount(inventory.getCount() - dto.getCount());
inventoryDao.update(inventory);
}
}
Seata事务执行流程:

⚡ 六、性能优化与最佳实践
6.1 事务性能优化策略
6.1.1 事务粒度控制
优化前:长事务:
java
@Service
public class LongTransactionService {
// ❌ 事务包含大量耗时操作
@Transactional
public void processOrderWithLongTransaction(Order order) {
// 数据库操作
orderDao.save(order);
// 耗时的外部调用(不应在事务中)
ExternalApiResult result = externalApiService.syncOrder(order);
// 复杂的业务计算
OrderCalculation calculation = complexCalculationService.calculate(order);
// 更多数据库操作
orderDao.update(calculation);
// 文件系统操作(不应在事务中)
fileService.generateOrderFile(order);
}
}
优化后:短事务:
java
@Service
public class OptimizedTransactionService {
// ✅ 将事务范围缩小到仅数据库操作
public void processOrderWithShortTransaction(Order order) {
// 事务1:保存订单
saveOrder(order);
// 非事务:外部调用
ExternalApiResult result = externalApiService.syncOrder(order);
// 非事务:复杂计算
OrderCalculation calculation = complexCalculationService.calculate(order);
// 事务2:更新订单
updateOrder(calculation);
// 非事务:文件生成
fileService.generateOrderFile(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveOrder(Order order) {
orderDao.save(order);
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateOrder(OrderCalculation calculation) {
orderDao.update(calculation);
}
}
6.1.2 只读事务优化
只读事务配置:
typescript
@Service
public class QueryService {
// ✅ 明确指定为只读事务,性能更好
@Transactional(readOnly = true)
public Order getOrderById(Long orderId) {
return orderDao.findById(orderId);
}
@Transactional(readOnly = true)
public List<Order> getOrdersByStatus(OrderStatus status) {
return orderDao.findByStatus(status);
}
// ✅ 复杂查询使用只读事务
@Transactional(readOnly = true, timeout = 30)
public OrderReport generateOrderReport(Date startDate, Date endDate) {
List<Order> orders = orderDao.findByDateRange(startDate, endDate);
return orderReportService.generate(orders);
}
}
只读事务性能优势:
| 特性 | 普通事务 | 只读事务 |
|---|---|---|
| 数据库连接 | 写连接 | 读连接 |
| 锁机制 | 排他锁 | 共享锁 |
| 性能开销 | 较高 | 较低 |
| 适用场景 | 增删改操作 | 查询操作 |
6.2 事务监控与诊断
6.2.1 事务监控指标
java
@Component
public class TransactionMonitor {
private static final Logger logger = LoggerFactory.getLogger(TransactionMonitor.class);
@EventListener
public void handleTransactionEvent(TransactionApplicationEvent event) {
if (event instanceof TransactionAfterCompletionEvent) {
TransactionAfterCompletionEvent completionEvent = (TransactionAfterCompletionEvent) event;
int status = completionEvent.getTransactionStatus().getCompletionStatus();
switch (status) {
case TransactionStatus.STATUS_COMMITTED:
logger.info("事务提交成功: {}", completionEvent.getTransactionContext());
break;
case TransactionStatus.STATUS_ROLLED_BACK:
logger.warn("事务回滚: {}", completionEvent.getTransactionContext());
break;
default:
logger.info("事务状态: {}", status);
}
}
}
}
6.2.2 慢事务检测
java
@Aspect
@Component
public class SlowTransactionAspect {
private static final long SLOW_TRANSACTION_THRESHOLD = 1000; // 1秒
@Around("@annotation(org.springframework.transaction.annotation.Transactional)")
public Object monitorTransactionPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result;
try {
result = joinPoint.proceed();
return result;
} finally {
long duration = System.currentTimeMillis() - startTime;
if (duration > SLOW_TRANSACTION_THRESHOLD) {
String methodName = joinPoint.getSignature().getName();
logger.warn("慢事务警告: 方法 {} 执行时间 {}ms", methodName, duration);
}
}
}
}
6.3 事务管理最佳实践清单
开发规范:

🎯 七、总结与建议
7.1 核心要点回顾
- 事务传播机制:正确理解7种传播行为的区别,合理选择传播方式
- 嵌套事务:掌握保存点机制,适合逻辑嵌套回滚场景
- 失效场景:避免方法访问修饰、同类调用、异常处理等常见陷阱
- 分布式事务:根据业务场景选择合适的分布式事务解决方案
- 性能优化 :控制事务粒度,使用只读事务,避免长事务
7.2 不同场景的事务选择指南
场景对照表:
| 业务场景 | 推荐传播行为 | 事务类型 | 隔离级别 | 超时设置 |
|---|---|---|---|---|
| 单表CRUD操作 | REQUIRED | 本地事务 | READ_COMMITTED | 默认 |
| 跨表操作 | REQUIRED | 本地事务 | READ_COMMITTED | 30秒 |
| 日志记录 | REQUIRES_NEW | 独立事务 | READ_COMMITTED | 10秒 |
| 批量导入 | NESTED | 嵌套事务 | READ_COMMITTED | 根据数据量 |
| 报表查询 | SUPPORTS | 只读事务 | READ_COMMITTED | 60秒 |
| 支付处理 | REQUIRED | 本地事务 | SERIALIZABLE | 15秒 |
| 跨服务调用 | 分布式事务 | Seata/MQ | - | - |
7.3 实战建议
开发阶段:
- 明确事务边界:仔细分析业务逻辑,确定事务的开始和结束点
- 选择合适传播:根据业务需求选择合适的事务传播行为
- 异常处理规范:明确定义哪些异常需要回滚,哪些不需要
- 编写测试用例 :覆盖正常、异常、边界等各种场景 运维阶段:
- 监控事务性能:重点关注慢事务和频繁回滚的事务
- 定期检查死锁:监控数据库死锁情况,优化SQL语句
- 告警机制:设置合理的事务告警阈值,及时发现问题
- 容量规划 :根据事务量评估数据库连接池大小 故障处理:
- 快速定位问题:通过日志和监控快速定位事务问题
- 数据修复:对于已发生的数据不一致,及时进行数据修复
- 根因分析:深入分析事务失效的根本原因,制定改进措施
- 预案制定 :制定分布式事务失败的各种处理预案
🔧 附录:事务管理工具类
scss
/**
* 事务管理工具类
* 提供常用的事务操作方法
*/
@Component
public class TransactionUtils {
@Autowired
private PlatformTransactionManager transactionManager;
/**
* 在事务中执行操作
*/
public <T> T executeInTransaction(TransactionCallback<T> action) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
return transactionTemplate.execute(action);
}
/**
* 在新事务中执行操作
*/
public <T> T executeInNewTransaction(TransactionCallback<T> action) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
return transactionTemplate.execute(action);
}
/**
* 在嵌套事务中执行操作
*/
public <T> T executeInNestedTransaction(TransactionCallback<T> action) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
return transactionTemplate.execute(action);
}
/**
* 只读事务执行查询
*/
public <T> T executeInReadOnlyTransaction(TransactionCallback<T> action) {
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setReadOnly(true);
return transactionTemplate.execute(action);
}
}
免责声明:本文中的示例代码仅供学习参考,实际应用中请根据具体业务场景进行调整。事务管理是企业级开发的核心技能,建议在实际项目中深入实践和总结经验。