真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么解決數(shù)據(jù)庫事務居然沒生效問題

本篇內(nèi)容介紹了“怎么解決數(shù)據(jù)庫事務居然沒生效問題”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)公司主要業(yè)務有網(wǎng)站營銷策劃、成都網(wǎng)站設計、做網(wǎng)站、微信公眾號開發(fā)、微信小程序開發(fā)、H5高端網(wǎng)站建設、程序開發(fā)等業(yè)務。一次合作終身朋友,是我們奉行的宗旨;我們不僅僅把客戶當客戶,還把客戶視為我們的合作伙伴,在開展業(yè)務的過程中,公司還積累了豐富的行業(yè)經(jīng)驗、成都全網(wǎng)營銷推廣資源和合作伙伴關系資源,并逐漸建立起規(guī)范的客戶服務和保障體系。 

Spring聲明式事務提供給 Javaer 們方便的事務配置方式,再搭配Spring  Boot自動配置,基本只需在方法上添加@Transactional注解,即可瞬間開啟方法的事務性配置。

  • 但僅為方法添加@Transactional注解

怎么解決數(shù)據(jù)庫事務居然沒生效問題

你就以為這就夠了嗎?

事務未被正確處理,一般不會導致停止服務,更不易在測試階段復現(xiàn)。但隨系統(tǒng)業(yè)務越來越復雜,就會帶來大量數(shù)據(jù)不一致問題,隨后就是大量線上問題而后人工排查檢修數(shù)據(jù)。

1 你的Spring事務怎么才算生效?

使用@Transactional開啟聲明式事務時, 靈魂發(fā)問:事務生效了嗎?

案例

用戶表實體類

怎么解決數(shù)據(jù)庫事務居然沒生效問題 

DAO 層

根據(jù)username查詢所有數(shù)據(jù)

@Repository public interface UserRepository extends JpaRepository {     List findByName(String name); }

Service層

UserService類

負責業(yè)務邏輯處理,包括如下方法:

createUserWrong1調(diào)用private方法:

怎么解決數(shù)據(jù)庫事務居然沒生效問題

createUserPrivate,被@Transactional注解。當傳入的用戶名包含test則拋異常,讓用戶的創(chuàng)建操作失敗,期望事務回滾:

怎么解決數(shù)據(jù)庫事務居然沒生效問題

getUserCount

怎么解決數(shù)據(jù)庫事務居然沒生效問題 

Controller層

調(diào)用一下剛才定義的UserService中的入口方法createUserWrong1。

怎么解決數(shù)據(jù)庫事務居然沒生效問題

測試結果

即便用戶名不合法,用戶也能創(chuàng)建成功。刷新瀏覽器,多次發(fā)現(xiàn)非法用戶注冊。

2 @Transactional怎么確保生效?

除非特殊配置(比如使用AspectJ靜態(tài)織入實現(xiàn)AOP),否則只有定義在public方法上的@Transactional才能生效。

Spring默認通過動態(tài)代理實現(xiàn)AOP,對目標方法增強,private方法無法代理到,自然也無法動態(tài)增強事務處理邏輯。

那簡單,把createUserPrivate方法改為public即可。

在UserService中再建一個入口方法createUserWrong2,來調(diào)用這個public方法再次嘗試:

public int createUserWrong2(String name) {     try {         this.createUserPublic(new UserEntity(name));     } catch (Exception ex) {         log.error("create user failed because {}", ex.getMessage());     }     return userRepository.findByName(name).size(); }  //標記了@Transactional的public方法 @Transactional public void createUserPublic(UserEntity entity) {     userRepository.save(entity);     if (entity.getName().contains("test"))         throw new RuntimeException("invalid username!"); }

新的createUserWrong2方法事務同樣不生效。

必須通過代理過的類從外部調(diào)用目標方法

要調(diào)用增強過的方法必然是調(diào)用代理后的對象。

嘗試修改UserService,注入一個self,然后再通過self實例調(diào)用標記有@Transactional注解的createUserPublic方法。設置斷點可以看到,self是由Spring通過CGLIB方式增強過的類。

CGLIB通過繼承方式實現(xiàn)代理類,private方法在子類不可見,自然也就無法進行事務增強;

this指針代表對象自己,Spring不可能注入this,所以通過this訪問方法必然不是代理。

把this改為self,在Controller中調(diào)用createUserRight方法可以驗證事務生效了:非法的用戶注冊操作可以回滾。

雖然在UserService內(nèi)部注入自己調(diào)用自己的createUserPublic可以正確實現(xiàn)事務,但這不符合習慣用法。更合理的實現(xiàn)方式是,讓Controller直接調(diào)用之前定義的UserService的createUserPublic方法。

@GetMapping("right2") public int right2(@RequestParam("name") String name) {     try {         userService.createUserPublic(new UserEntity(name));     } catch (Exception ex) {         log.error("create user failed because {}", ex.getMessage());     }     return userService.getUserCount(name); }

this自調(diào)用/self調(diào)用/Controller調(diào)用UserService

怎么解決數(shù)據(jù)庫事務居然沒生效問題
  • this自調(diào)用

        無法走到Spring代理類

  • 后兩種

        調(diào)用的Spring注入的UserService,通過代理調(diào)用才有機會對createUserPublic方法進行動態(tài)增強。

推薦在開發(fā)時打開相關Debug日志,以了解Spring事務實現(xiàn)的細節(jié)。

比如JPA數(shù)據(jù)庫訪問,可以這么開啟Debug日志:

logging.level.org.springframework.orm.jpa=DEBUG

開啟日志后再比較下在UserService中this調(diào)用、Controller中通過注入的UserService  Bean調(diào)用createUserPublic的區(qū)別。

很明顯,this調(diào)用因沒走代理,事務沒有在createUserPublic生效,只在Repository的save生效:

// 在UserService中通過this調(diào)用public的createUserPublic [23:04:30.748] [http-nio-45678-exec-5] [DEBUG] [o.s.orm.jpa.JpaTransactionManager:370 ] -  Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]:  PROPAGATION_REQUIRED,ISOLATION_DEFAULT  [DEBUG] [o.s.orm.jpa.JpaTransactionManager       :370 ] - Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT //在Controller中通過注入的UserService Bean調(diào)用createUserPublic [10:10:47.750] [http-nio-45678-exec-6] [DEBUG] [o.s.orm.jpa.JpaTransactionManager       :370 ] - Creating new transaction with name [org.geekbang.time.commonmistakes.transaction.demo1.UserService.createUserPublic]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

這種實現(xiàn)在Controller里處理異常顯得繁瑣,還不如直接把createUserWrong2加@Transactional注解,然后在Controller中直接調(diào)用該方法。

“怎么解決數(shù)據(jù)庫事務居然沒生效問題”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!


當前標題:怎么解決數(shù)據(jù)庫事務居然沒生效問題
分享網(wǎng)址:http://weahome.cn/article/ggisdp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部