Spring Boot 七种事件传播活动只有 REQUIRES_NEW 和 NESTED 支持部门回滚的分析
Spring Boot 七种事件传播活动支持部门回滚的分析支持部门回滚的传播活动
[*]REQUIRES_NEW:始终开启新事件,独立于外部事件,失败时仅自身回滚。
[*]NESTED:在当前事件中创建生存点(Savepoint),可局部回滚到生存点,不影响外部事件整体提交。
代码示例:利用 REQUIRES_NEW 实现部门回滚
1. 交易服务层(独立事件)
@Service
public class TransactionService {
@Autowired
private TradeRepository tradeRepository;
// 使用 REQUIRES_NEW,每个交易独立事务
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void processTrade(Trade trade) {
try {
// 模拟业务逻辑(如保存交易)
tradeRepository.save(trade);
if (trade.getId() == 3) { // 模拟交易3失败
throw new RuntimeException("Transaction 3 failed");
}
} catch (Exception e) {
// 本地异常处理,但事务仍会回滚
throw e;
}
}
}
2. 批量使命协调者
@Service
public class BatchProcessor {
@Autowired
private TransactionService transactionService;
// 批量任务不开启事务(NOT_SUPPORTED)
@Transactional(propagation = Propagation.NOT_SUPPORTED)
public void executeBatch(List<Trade> trades) {
for (Trade trade : trades) {
try {
transactionService.processTrade(trade);
} catch (Exception e) {
// 记录错误但继续处理其他交易
System.out.println("Trade " + trade.getId() + " failed!");
}
}
}
}
3. 测试用例
@SpringBootTest
public class BatchTest {
@Autowired
private BatchProcessor batchProcessor;
@Autowired
private TradeRepository tradeRepository;
@Test
public void testBatchProcessing() {
List<Trade> trades = Arrays.asList(
new Trade(1, "Success1"),
new Trade(2, "Success2"),
new Trade(3, "Failed")// 交易3会失败
);
batchProcessor.executeBatch(trades);
// 验证:交易1和2已提交,交易3未提交
assertEquals(2, tradeRepository.count());
}
}
代码示例:利用 NESTED 实现部门回滚
1. 交易服务层(嵌套事件)
@Service
public class TransactionService {
@Autowired
private TradeRepository tradeRepository;
// 使用 NESTED,在外部事务中创建保存点
@Transactional(propagation = Propagation.NESTED, rollbackFor = Exception.class)
public void processTradeWithNested(Trade trade) {
try {
tradeRepository.save(trade);
if (trade.getId() == 3) {
throw new RuntimeException("Transaction 3 failed");
}
} catch (Exception e) {
throw e; // 回滚到保存点,但外部事务可继续提交其他交易
}
}
}
2. 批量使命协调者(需开启外部事件)
@Service
public class BatchProcessor {
@Autowired
private TransactionService transactionService;
// 开启外部事务(REQUIRED)
@Transactional(propagation = Propagation.REQUIRED)
public void executeBatchWithNested(List<Trade> trades) {
for (Trade trade : trades) {
try {
transactionService.processTradeWithNested(trade);
} catch (Exception e) {
System.out.println("Trade " + trade.getId() + " failed!");
// 继续处理其他交易
}
}
// 手动提交外部事务(可选,但通常由Spring自动管理)
}
}
传播活动对比表格
传播活动是否支持部门回滚实用场景代码示例方法REQUIRED❌ 不支持继承父事件,失败时所有操纵回滚-REQUIRES_NEW✅ 支持独立事件,失败不影响其他交易processTrade()SUPPORTS❌ 不支持无事件或依赖父事件-NOT_SUPPORTED❌ 不支持挂起父事件,无事件实行-MANDATORY❌ 不支持必须存在父事件-NEVER❌ 不支持禁止存在父事件-NESTED✅ 支持在父事件中创建生存点,局部回滚processTradeWithNested() 关键阐明
[*] REQUIRES_NEW
[*]每个交易独立开启事件,失败时仅自身回滚,其他交易不受影响。
[*]实用场景:完全独立的交易,彼此无依赖。
[*] NESTED
[*]在父事件中创建生存点,失败时回滚到生存点,但父事件仍可提交。
[*]实用场景:交易间有弱关联,需局部回滚但整体提交成功。
注意:利用 NESTED 需确保数据库和驱动支持生存点(如MySQL/PostgreSQL)。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]