java - 如何在Spring的@Transaction層面上對異常進(jìn)行日志記錄?
問題描述
在沒使用@Transaction之前,我的業(yè)務(wù)代碼模型大概就是下面這樣:
DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(def);try { studentMapper.insertOnestdent(student); logger.info('Insert one record successfully: ' + student.toString());} catch (Exception ex) { dataSourceTransactionManager.rollback(transactionStatus); // ex.printStackTrace(); logger.error('Insert one record unsuccessfully: ' + student.toString()); return false;}dataSourceTransactionManager.commit(transactionStatus);return true;
類似上面這樣的話不管我上面的數(shù)據(jù)庫操作執(zhí)行成功還是執(zhí)行失敗,我在日志中都可以得到反饋。
但是上面這樣的做法,會造成大量的代碼的重復(fù),利用spring提供的aop可以實(shí)現(xiàn)這樣的日志功能,但是后來看文檔發(fā)現(xiàn)有一個@Transaction注解,使用這個注解,代碼可以簡化成下面這個樣子:
@Transactional(rollbackFor = Exception.class) public boolean insertOneStudent(Student student) {studentMapper.insertOneStudent(student);logger.info('Insert one student successfully' + student.toString());return true; }
這樣當(dāng)數(shù)據(jù)庫操作執(zhí)行成功的時候我可以日志中成功的進(jìn)行記錄,但是這樣的話當(dāng)插入操作執(zhí)行失敗的時候我應(yīng)該如何在日志中進(jìn)行記錄。
我現(xiàn)在的初步想法是自己手動實(shí)現(xiàn)一個類似@Transaction的動態(tài)反射的功能,這樣每個要影響數(shù)據(jù)庫中的數(shù)據(jù)修改的方法執(zhí)行的時候我都在動態(tài)反射的invoke()方法中進(jìn)行異常的try catch的處理。但是不知道spring是否內(nèi)置這樣的功能?
p.s: 我盡量想將數(shù)據(jù)庫的操作與處理全部放在service層面來處理,不想將日志記錄的往上面拋。
問題解答
回答1:insertOneStudent方法整個try catch
try {...} catch (Exception e) { logger.error(e.getMessage(), e); throw e;}
或者實(shí)現(xiàn)@RestControllerAdvice,在里面統(tǒng)一打印異常日志像這樣:
@RestControllerAdvicepublic class MyExceptionHandler { @ExceptionHandler(value = Exception.class) public Object exceptionHandler(HttpServletRequest request, Exception exception) {logger.warn('異常:', exception);... }}回答2:
spring也有提供切面的異常處理
<!--aop配置 --> <aop:config><!-- 業(yè)務(wù)類切面 --><aop:pointcut expression='【這里填寫切面的匹配規(guī)則】' /><!-- 異常處理 --><aop:aspect ref='【處理異常的類ID】'> <aop:after-throwing method='【處理異常的方法名稱】' pointcut-ref='【切面ID】' throwing='e' /></aop:aspect> </aop:config>
當(dāng)然,有xml配置就會有注解配置。主要有下面幾個注解
@Aspect 聲明切面配置
@Pointcut 聲明切面
@AfterThrowing 聲明處理方法
注意事項(xiàng):
處理異常的類是不需要實(shí)現(xiàn)任何接口和繼承任何類的。
處理異常的方法要聲明兩個參數(shù)(不聲明也可以,獲取不了異常信息而已),舉個例子
public void test(JoinPoint joinPoint, Exception e)
其中joinPoint參數(shù)可以獲取拋出異常的方法參數(shù)信息,Exception對象就不用說了吧。
以上內(nèi)容僅做參考,spring的版本不同也可能會導(dǎo)致上述說明和實(shí)際情況有差異,想獲取標(biāo)準(zhǔn)的說明請參閱Spring的官方文檔
相關(guān)文章:
1. python文檔怎么查看?2. python - pycharm 自動刪除行尾空格3. 安全性測試 - nodejs中如何防m(xù)ySQL注入4. python - pandas按照列A和列B分組,將列C求平均數(shù),怎樣才能生成一個列A,B,C的dataframe5. python - Pycharm的Debug用不了6. html - eclipse 標(biāo)簽錯誤7. python 利用subprocess庫調(diào)用mplayer時發(fā)生錯誤8. 請問PHPstudy中的數(shù)據(jù)庫如何創(chuàng)建索引9. datetime - Python如何獲取當(dāng)前時間10. javascript - 有適合開發(fā)手機(jī)端Html5網(wǎng)頁小游戲的前端框架嗎?
