事务传播行为
事务传播行为定义了事务方法相互调用时的处理策略。
七种传播行为
| 传播行为 | 说明 | 当前有事务 | 当前无事务 |
|---|---|---|---|
| REQUIRED | 需要事务(默认) | 加入当前事务 | 新建事务 |
| SUPPORTS | 支持事务 | 加入当前事务 | 非事务执行 |
| MANDATORY | 强制事务 | 加入当前事务 | 抛异常 |
| REQUIRES_NEW | 新建事务 | 挂起当前,新建 | 新建事务 |
| NOT_SUPPORTED | 不支持事务 | 挂起当前,非事务 | 非事务执行 |
| NEVER | 不允许事务 | 抛异常 | 非事务执行 |
| NESTED | 嵌套事务 | 创建嵌套事务 | 新建事务 |
REQUIRED - 默认行为
Java
@Service
public class OrderService {
@Autowired
private ItemService itemService;
// 外层事务
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder(Order order) {
orderDao.insert(order);
// 加入同一事务,任一失败全部回滚
itemService.decreaseStock(order.getItemId(), order.getQuantity());
}
}
@Service
public class ItemService {
@Transactional(propagation = Propagation.REQUIRED)
public void decreaseStock(Long itemId, int quantity) {
itemDao.decreaseStock(itemId, quantity);
}
}
执行流程:OrderService创建事务 → ItemService加入事务 → 统一提交或回滚
REQUIRES_NEW - 独立事务
Java
@Service
public class OrderService {
@Autowired
private LogService logService;
@Transactional(propagation = Propagation.REQUIRED)
public void createOrder(Order order) {
try {
orderDao.insert(order);
// doSomething抛异常
} catch (Exception e) {
// 日志独立事务,不受外层回滚影响
logService.saveLog("订单创建失败: " + e.getMessage());
throw e; // 外层事务回滚
}
}
}
@Service
public class LogService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void saveLog(String message) {
logDao.insert(new Log(message));
// 独立提交,外层回滚不影响日志记录
}
}
适用场景:日志记录、审计跟踪等需要独立提交的操作
NESTED - 嵌套事务
Java
@Service
public class BatchService {
@Autowired
private ItemService itemService;
@Transactional(propagation = Propagation.REQUIRED)
public void batchProcess(List<Item> items) {
for (Item item : items) {
try {
// 嵌套事务,可独立回滚
itemService.process(item);
} catch (Exception e) {
// 单个失败不影响其他项,外层事务继续
log.warn("处理失败: {}", item.getId());
}
}
}
}
@Service
public class ItemService {
@Transactional(propagation = Propagation.NESTED)
public void process(Item item) {
itemDao.update(item);
// 异常只回滚当前嵌套事务
}
}
NESTED vs REQUIRES_NEW:
- NESTED:外层回滚时嵌套事务也回滚
- REQUIRES_NEW:完全独立,互不影响
SUPPORTS - 可选事务
Java
@Service
public class QueryService {
// 可在事务或非事务环境下执行
@Transactional(propagation = Propagation.SUPPORTS)
public List<User> findUsers() {
return userDao.findAll();
}
}
// 事务环境调用 - 加入事务
userService.findUsers();
// 非事务环境调用 - 直接执行
queryService.findUsers();
MANDATORY - 强制事务
Java
@Service
public class CoreService {
// 必须在事务中被调用
@Transactional(propagation = Propagation.MANDATORY)
public void criticalOperation() {
// 核心业务操作
}
}
// 错误:直接调用抛异常
coreService.criticalOperation();
// IllegalTransactionStateException: No existing transaction found
// 正确:在事务中调用
@Transactional
public void wrapper() {
coreService.criticalOperation();
}
NOT_SUPPORTED - 非事务执行
Java
@Service
public class ReportService {
@Autowired
private ReportDao reportDao;
// 长时间查询,不需要事务
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void generateLargeReport() {
// 避免长时间持有数据库连接
List<Data> data = reportDao.fetchLargeData();
// 处理数据...
}
}
NEVER - 禁止事务
Java
@Service
public class CacheService {
// 确保不在事务中执行
@Transactional(propagation = Propagation.NEVER)
public void refreshCache() {
cache.clear();
cache.load();
}
}
// 错误:在事务中调用抛异常
@Transactional
public void refresh() {
cacheService.refreshCache(); // IllegalTransactionStateException
}
传播行为选择指南
| 场景 | 推荐传播行为 |
|---|---|
| 常规业务操作 | REQUIRED(默认) |
| 日志/审计独立提交 | REQUIRES_NEW |
| 批量操作部分失败允许继续 | NESTED |
| 只读查询优化 | SUPPORTS |
| 长时间非事务操作 | NOT_SUPPORTED |
要点总结
- REQUIRED:最常用,有事务则加入
- REQUIRES_NEW:独立事务,适合日志记录
- NESTED:嵌套事务,支持部分回滚
- REQUIRES_NEW完全独立,NESTED外层回滚会影响嵌套
- MANDATORY/NEVER用于强制约束调用方式
📝 发现内容有误?点击此处直接编辑