Author:赵志乾
Date:2019-06-12
Declaration:All Right Reserved!!!
踩坑:
前提:切面逻辑和业务代码均未做异常处理。
场景:项目采用多数据源配置,在切面中完成数据源的动态切换。当业务代码抛异常后,没有自动切回默认数据源。
做法:
public Object around(ProceedingJoinPoint point, ChangeDataSource source) throws Throwable {
//切换数据源
if (!StringUtils.isEmpty(source.source())) {
DynamicDataSource.putDataSource(source.source());
}
//执行业务代码
Object obj = point.proceed();
//切换回默认数据源
DynamicDataSource.putDataSource("default");
return obj;
}
解决方案:
上述问题是因异常抛出导致未执行切回默认数据源逻辑,故可依据实际的需要采用如下两种方案解决:
方案1:业务代码中将异常捕获,不进行抛出。该方案的限制性较强,有时不满足要求,故不建议采用。
方案2:在切面逻辑中使用finally子句确保切回默认数据源逻辑会执行。如下:
public Object around(ProceedingJoinPoint point, ChangeDataSource source) throws Throwable {
try{
//切换数据源
if (!StringUtils.isEmpty(source.source())) {
DynamicDataSource.putDataSource(source.source());
}
//执行业务代码
Object obj = point.proceed();
}
finally{
//切换回默认数据源
DynamicDataSource.putDataSource("default");
}
return obj;
}
建议:
凡是某些逻辑需要必须执行的,建议放在finally子句中,保证对应逻辑一定会执行到(虚拟机宕掉的情况除外)。