问题描述
数据推送只有部分推送成功,推送失败的报查询不存在的异常,经排查是没保存数据库成功就去查询了,因为发MQ消息是异步的。推送的逻辑是在审核成功之后,审核里面操作比较多,开启了事务,有:一系列的数据库操作,其中一个操作异常就全部回滚。使用的是Transaction实现事务。
方案一:
具体实现代码,通过spring 注解Transactional实现事务,使用TransactionSynchronizationManger注册一个异步afterCommit事件实现提交事务后再发消息。
classA implements InterfaceA{
Result<String> methodA(){
boolean result = methodAWrapper();
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
//审核成功无异常才发MQ消息
if (result) {
sendAddMqMessage();
}
}
});
return Result.success("审核成功");
}
}
缺点:把异常信息直接抛给前端了,一大串英文错误很不友好,虽然自定义异常然后可以全局捕获异常,但是我们只希望返回给前端的信息就只是“审核成功”或”审核失败“,有些异常不是自定义异常时就是默认处理了。举个栗子:feign调服务,服务不可用一般都会主动捕获这个连接异常,若没设置feign失败策略,就把不友好异常给前端了。
方案二:
classA implements InterfaceA{
Result<String> methodA(){
try{
((InterfaceA)AopContext.currentProxy()).methodB();
} catch(Exception e)
{
log.error("异常",e);
return Result.failed("审核失败");
}
return Result.success("审核成功");
}
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
methodB(){
//操作数据库
}
}
优点:既可以使用注解Transactional实现事务,又可以捕获异常;
缺点:多定义了一个方法.
期间顺便学习了Transactional的7种传播机制,决定使用默认的required就可以。