久久久精品一区ed2k-女人被男人叉到高潮的视频-中文字幕乱码一区久久麻豆樱花-俄罗斯熟妇真实视频

怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題

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

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

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

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

怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題

你就以為這就夠了嗎?

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

1 你的Spring事務(wù)怎么才算生效?

使用@Transactional開(kāi)啟聲明式事務(wù)時(shí), 靈魂發(fā)問(wèn):事務(wù)生效了嗎?

案例

用戶(hù)表實(shí)體類(lèi)

怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題 

DAO 層

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

@Repository public interface UserRepository extends JpaRepository<UserEntity, Long> {     List<UserEntity> findByName(String name); }

Service層

UserService類(lèi)

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

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

怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題

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

怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題

getUserCount

怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題 

Controller層

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

怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題

測(cè)試結(jié)果

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

2 @Transactional怎么確保生效?

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

Spring默認(rèn)通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)AOP,對(duì)目標(biāo)方法增強(qiáng),private方法無(wú)法代理到,自然也無(wú)法動(dòng)態(tài)增強(qiáng)事務(wù)處理邏輯。

那簡(jiǎn)單,把createUserPrivate方法改為public即可。

在UserService中再建一個(gè)入口方法createUserWrong2,來(lái)調(diào)用這個(gè)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(); }  //標(biāo)記了@Transactional的public方法 @Transactional public void createUserPublic(UserEntity entity) {     userRepository.save(entity);     if (entity.getName().contains("test"))         throw new RuntimeException("invalid username!"); }

新的createUserWrong2方法事務(wù)同樣不生效。

必須通過(guò)代理過(guò)的類(lèi)從外部調(diào)用目標(biāo)方法

要調(diào)用增強(qiáng)過(guò)的方法必然是調(diào)用代理后的對(duì)象。

嘗試修改UserService,注入一個(gè)self,然后再通過(guò)self實(shí)例調(diào)用標(biāo)記有@Transactional注解的createUserPublic方法。設(shè)置斷點(diǎn)可以看到,self是由Spring通過(guò)CGLIB方式增強(qiáng)過(guò)的類(lèi)。

CGLIB通過(guò)繼承方式實(shí)現(xiàn)代理類(lèi),private方法在子類(lèi)不可見(jiàn),自然也就無(wú)法進(jìn)行事務(wù)增強(qiáng);

this指針代表對(duì)象自己,Spring不可能注入this,所以通過(guò)this訪問(wèn)方法必然不是代理。

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

雖然在UserService內(nèi)部注入自己調(diào)用自己的createUserPublic可以正確實(shí)現(xiàn)事務(wù),但這不符合習(xí)慣用法。更合理的實(shí)現(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ù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題
  • this自調(diào)用

        無(wú)法走到Spring代理類(lèi)

  • 后兩種

        調(diào)用的Spring注入的UserService,通過(guò)代理調(diào)用才有機(jī)會(huì)對(duì)createUserPublic方法進(jìn)行動(dòng)態(tài)增強(qiáng)。

推薦在開(kāi)發(fā)時(shí)打開(kāi)相關(guān)Debug日志,以了解Spring事務(wù)實(shí)現(xiàn)的細(xì)節(jié)。

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

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

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

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

// 在UserService中通過(guò)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中通過(guò)注入的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

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

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

網(wǎng)頁(yè)題目:怎么解決數(shù)據(jù)庫(kù)事務(wù)居然沒(méi)生效問(wèn)題
當(dāng)前地址:http://sd-ha.com/article18/ggisdp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化手機(jī)網(wǎng)站建設(shè)、服務(wù)器托管、網(wǎng)站營(yíng)銷(xiāo)、、響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)