SpringBoot異步方法捕捉異常詳解
本文實例為大家分享了SpringBoot異步方法捕捉異常的具體代碼,供大家參考,具體內容如下
由于項目中定時器都采用異步執(zhí)行方式
需要定時監(jiān)控異步方法執(zhí)行進度,異常情況
1 執(zhí)行進度
可以設置是否在執(zhí)行,內存中添加執(zhí)行標識即可。
防止多次執(zhí)行可以通過攔截器對此,標識來判斷,防止多次執(zhí)行定時器
2 異常捕捉
監(jiān)控異步方法執(zhí)行是否異常。
1 無返回值
配置AsyncExceptionConfig類,統(tǒng)一處理。
定義異常捕獲配置類AsyncExceptionConfig,配置類里面定義SpringAsyncExceptionHandler 方法實現(xiàn)AsyncUncaughtExceptionHandler 接口。
代碼如下:
package cn.bwjf.config;
import cn.bwjf.common.constant.InitServiceIdEnum;
import cn.bwjf.common.tools.InitServiceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
/**
* @description : 異常捕獲配置類
* @author : tizzy <br/>
* @version : 1.0
* @date 2019/9/21
*/
@Configuration
@Slf4j
public class AsyncExceptionConfig implements AsyncConfigurer {
/**
* @description : 設置異步方法線程參數(shù)
* @author : tizzy
* @version : 1.0
*/
@Bean
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//根據(jù)自己機器配置
executor.setCorePoolSize(8);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(64);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("SpringAsyncThread-");
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SpringAsyncExceptionHandler();
}
class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
log.info("------我是Async無返回方法的異常處理方法---------");
//通過反射獲取各個初始化方法名字
String methodName = method.getName();
log.info(" 當前異常方法名 == {} " , methodName);
//根據(jù)方法名字 記錄異常 略。。。。
log.info("------我是Async無返回方法的異常處理方法---------");
}
}
}
2 有返回值
返回值 用 AsyncResult 包裝返回
AsyncResult是Future接口的子類,所以也可以通過future.get()獲取返回值的時候捕獲ExcecutionException。
@Async
public Future<String> asyncMethod() {
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
調用
try {
Future future = service.asyncMethod();
future.get();
} catch (ExecutionException e) {
logger.error("exception occurs", e);
} catch (InterruptedException e) {
logger.error("exception occurs", e);
}
什么是 Future類型?
Future是對于具體的 Runnable或者 Callable任務的執(zhí)行結果進行取消、查詢是否完成、獲取結果的接口。必要時可以通過get方法獲取執(zhí)行結果,該方法會阻塞直到任務返回結果。
它的接口定義如下:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
它聲明這樣的五個方法:
cancel方法用來取消任務,如果取消任務成功則返回true,如果取消任務失敗則返回false。參數(shù)mayInterruptIfRunning表示是否允許取消正在執(zhí)行卻沒有執(zhí)行完畢的任務,如果設置true,則表示可以取消正在執(zhí)行過程中的任務。如果任務已經完成,則無論mayInterruptIfRunning為true還是false,此方法肯定返回false,即如果取消已經完成的任務會返回false;如果任務正在執(zhí)行,若mayInterruptIfRunning設置為true,則返回true,若mayInterruptIfRunning設置為false,則返回false;如果任務還沒有執(zhí)行,則無論mayInterruptIfRunning為true還是false,肯定返回true。
isCancelled方法表示任務是否被取消成功,如果在任務正常完成前被取消成功,則返回 true。
isDone方法表示任務是否已經完成,若任務完成,則返回true;
get()方法用來獲取執(zhí)行結果,這個方法會產生阻塞,會一直等到任務執(zhí)行完畢才返回;
get(long timeout, TimeUnit unit)用來獲取執(zhí)行結果,如果在指定時間內,還沒獲取到結果,就直接返回null。
也就是說Future提供了三種功能:
判斷任務是否完成;
能夠中斷任務;
能夠獲取任務執(zhí)行結果。
3 異步方法中事務
@Async調用中的事務處理機制
在@Async標注的方法,同時也適用了@Transactional進行了標注;在其調用數(shù)據(jù)庫操作之時,將無法產生事務管理的控制,原因就在于其是基于異步處理的操作。
正確做法
如何給這些操作添加事務管理呢?可以將需要事務管理操作的方法放置到異步方法內部,在內部被調用的方法上添加@Transactional.
例如:
方法A,使用了@Async/@Transactional來標注,但是無法產生事務控制的目的。
方法B,使用了@Async來標注, B中調用了C、D,C/D分別使用@Transactional做了標注,是可以實現(xiàn)事務控制的目的。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
解決Java導入excel大量數(shù)據(jù)出現(xiàn)內存溢出的問題
今天小編就為大家分享一篇解決Java導入excel大量數(shù)據(jù)出現(xiàn)內存溢出的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06
springBoot?@Scheduled實現(xiàn)多個任務同時開始執(zhí)行
這篇文章主要介紹了springBoot?@Scheduled實現(xiàn)多個任務同時開始執(zhí)行,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12

