日常Bug排查-拋異常不回滾
前言
日常Bug排查系列都是一些簡單Bug排查,筆者將在這里介紹一些排查Bug的簡單技巧,同時順便積累素材^_^。
Bug現場
最近有人反映java應用操作數據庫的時候,拋異常不回滾。這還了得,不過筆者篤定肯定是用法的鍋,不然就全亂套了。所以筆者去Review他的代碼。
代碼片段
- @Transacion(value="x")
- public void s1() throw MyException{
- update(1);
- throwBusinessException();
- update(2);
- }
乍看上去沒啥問題。
思路
筆者用@Transaction注解也用了好幾年了,從來沒遇到過拋異常不回滾的情況。看他的用法也和筆者差不多呀?
然后筆者稍微思索了會,發現我寫的代碼和出問題的這一段稍稍有些不一樣。我是這么寫的:
- @Transacion(value="transManager")
- public void s1(){
- update(1);
- update(2);
- }
貌似我從來沒有在函數上加過throw MyException,難道是這段有問題?翻看MyException代碼,發現它僅僅繼承了Exception。
- class MyEception extends Exception {
- }
好像就這點不一樣。而筆者自定義的Exception基本繼承了RuntimeException的。
翻下Spring源碼
按照這個思路,筆者去翻了下Spring的源碼,看下它在聲明式事務中的處理邏輯到底是什么,于是翻到了這一段處理事務異常的代碼:
- TransactionAspectSupport.java
- protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
- if (txInfo.transactionAttribute.rollbackOn(ex)) {
- }else{
- // We don't roll back on this exception.
- // Will still roll back if TransactionStatus.isRollbackOnly() is true.
- // 在checkedException的時候,不會被rollBack,會commit!!!
- }
- }
- @Override
- public boolean rollbackOn(Throwable ex) {
- return (ex instanceof RuntimeException || ex instanceof Error);
- }
看代碼邏輯就明白了,只有異常繼承RuntimeException或者Error的時候才會回滾!好了,讓業務開發改了下代碼,問題解決了。
總結
遇到問題時,找到出問題代碼段和類似的正確代碼段的不同處,以此為切入,往往能抓住線索。
本文轉載自微信公眾號「解Bug之路」,可以通過以下二維碼關注。轉載本文請聯系解Bug之路公眾號。