主程序同步調用發送消息接口,接口異常導致主流程回滾/失敗。
| 方案 | 做法 | 優點 | 缺點 |
|---|---|---|---|
| MQ 異步 | 主流程發送 MQ,消費者異步處理 | 完全解耦,高可用 | 引入中間件,複雜度上升 |
| 接口內部捕獲 | 發送接口 try-catch 吞掉異常 | 改動小,無額外組件 | 異常丟失,難追蹤 |
@Aspect
@Component
public class SendMessageAspect {
@Around("execution(* com.xxx.service.MessageSender.*(..))")
public Object handleException(ProceedingJoinPoint pjp) {
try {
return pjp.proceed();
} catch (Exception e) {
log.error("發送消息失敗", e);
return null; // 或默認返回值,不拋出
}
}
}
<context:component-scan> 預設不掃描 @Aspect,需加 @Component 或 XML include@AfterThrowing 仍會拋出異常,必須用 @Around + try-catch// A 方法:REQUIRED, rollback-for=Exception
void a() { b(); }
// B 方法:READ_ONLY (默認 REQUIRED)
void b() {
try { ... } catch (Exception e) { log.error(e); } // 吞掉異常
}
將查詢類方法 B 事務傳播設置為 NOT_SUPPORTED(不需要事務),或 SUPPORTS(跟隨外部事務但不標記回滾)。
<tx:method name="query*" propagation="NOT_SUPPORTED" read-only="true" />