91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

spring中聲明式事務(wù)實(shí)現(xiàn)原理猜想

Android編程精選 ? 來源:CSDN博客 ? 作者:一擼向北 ? 2021-10-13 09:20 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

@Transactional注解簡介

@Transactional是spring中聲明式事務(wù)管理的注解配置方式,相信這個(gè)注解的作用大家都很清楚。@Transactional注解可以幫助我們把事務(wù)開啟、提交或者回滾的操作,通過aop的方式進(jìn)行管理。

通過@Transactional注解就能讓spring為我們管理事務(wù),免去了重復(fù)的事務(wù)管理邏輯,減少對業(yè)務(wù)代碼的侵入,使我們開發(fā)人員能夠?qū)W⒂跇I(yè)務(wù)層面開發(fā)。

我們知道實(shí)現(xiàn)@Transactional原理是基于spring aop,aop又是動(dòng)態(tài)代理模式的實(shí)現(xiàn),通過對源碼的閱讀,總結(jié)出下面的步驟來了解實(shí)際中,在spring 是如何利用aop來實(shí)現(xiàn)@Transactional的功能的。

spring中聲明式事務(wù)實(shí)現(xiàn)原理猜想

首先,對于spring中aop實(shí)現(xiàn)原理有了解的話,應(yīng)該知道想要對一個(gè)方法進(jìn)行代理的話,肯定需要定義切點(diǎn)。在@Transactional的實(shí)現(xiàn)中,同樣如此,spring為我們定義了以 @Transactional 注解為植入點(diǎn)的切點(diǎn),這樣才能知道@Transactional注解標(biāo)注的方法需要被代理。

有了切面定義之后,在spring的bean的初始化過程中,就需要對實(shí)例化的bean進(jìn)行代理,并且生成代理對象。

生成代理對象的代理邏輯中,進(jìn)行方法調(diào)用時(shí),需要先獲取切面邏輯,@Transactional注解的切面邏輯類似于@Around,在spring中是實(shí)現(xiàn)一種類似代理邏輯。

@Transactional作用

根據(jù)上面的原理猜想,下面簡單介紹每個(gè)步驟的源碼以進(jìn)行驗(yàn)證。

首先是@Transactional,作用是定義代理植入點(diǎn)。我們知道代理對象創(chuàng)建的通過BeanPostProcessor的實(shí)現(xiàn)類AnnotationAwareAspectJAutoProxyCreatorpostProcessAfterInstantiation方法來實(shí)現(xiàn)個(gè),如果需要進(jìn)行代理,那么在這個(gè)方法就會(huì)返回一個(gè)代理對象給容器,同時(shí)判斷植入點(diǎn)也是在這個(gè)方法中。

那么下面開始分析,在配置好注解驅(qū)動(dòng)方式的事務(wù)管理之后,spring會(huì)在ioc容器創(chuàng)建一個(gè)BeanFactoryTransactionAttributeSourceAdvisor實(shí)例,這個(gè)實(shí)例可以看作是一個(gè)切點(diǎn),在判斷一個(gè)bean在初始化過程中是否需要?jiǎng)?chuàng)建代理對象,都需要驗(yàn)證一次BeanFactoryTransactionAttributeSourceAdvisor是否是適用這個(gè)bean的切點(diǎn)。如果是,就需要?jiǎng)?chuàng)建代理對象,并且把BeanFactoryTransactionAttributeSourceAdvisor實(shí)例注入到代理對象中。

前文我們知道在AopUtils#findAdvisorsThatCanApply中判斷切面是否適用當(dāng)前bean,可以在這個(gè)地方斷點(diǎn)分析調(diào)用堆棧,AopUtils#findAdvisorsThatCanApply一致調(diào)用,最終通過以下代碼判斷是否適用切點(diǎn)。

  • AbstractFallbackTransactionAttributeSource#computeTransactionAttribute(Method method, Class targetClass)這里可以根據(jù)參數(shù)打上條件斷點(diǎn)進(jìn)行調(diào)試分析調(diào)用棧,targetClass就是目標(biāo)class …一系列調(diào)用
  • 最終SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)
@Override
publicTransactionAttributeparseTransactionAnnotation(AnnotatedElementae){
//這里就是分析Method是否被@Transactional注解標(biāo)注,有的話,不用說BeanFactoryTransactionAttributeSourceAdvisor適配當(dāng)前bean,進(jìn)行代理,并且注入切點(diǎn)
//BeanFactoryTransactionAttributeSourceAdvisor
AnnotationAttributesattributes=AnnotatedElementUtils.getMergedAnnotationAttributes(ae,Transactional.class);
if(attributes!=null){
returnparseTransactionAnnotation(attributes);
}
else{
returnnull;
}
}

上面就是判斷是否需要根據(jù)@Transactional進(jìn)行代理對象創(chuàng)建的判斷過程。@Transactional的作用一個(gè)就是標(biāo)識(shí)方法需要被代理,一個(gè)就是攜帶事務(wù)管理需要的一些屬性信息。

動(dòng)態(tài)代理邏輯實(shí)現(xiàn)

【aop實(shí)現(xiàn)原理分析】中知道,aop最終的代理對象的代理方法是

  • DynamicAdvisedInterceptor#intercept

所以我們可以在這個(gè)方法斷點(diǎn)分析代理邏輯。往期的面試題,點(diǎn)擊查看

@Override
publicObjectintercept(Objectproxy,Methodmethod,Object[]args,MethodProxymethodProxy)throwsThrowable{
ObjectoldProxy=null;
booleansetProxyContext=false;
ClasstargetClass=null;
Objecttarget=null;
try{
if(this.advised.exposeProxy){
//Makeinvocationavailableifnecessary.
oldProxy=AopContext.setCurrentProxy(proxy);
setProxyContext=true;
}
//Maybenull.Getaslateaspossibletominimizethetimewe
//"own"thetarget,incaseitcomesfromapool...
target=getTarget();
if(target!=null){
targetClass=target.getClass();
}
//follow
Listchain=this.advised.getInterceptorsAndDynamicInterceptionAdvice(method,targetClass);
ObjectretVal;
//CheckwhetherweonlyhaveoneInvokerInterceptor:thatis,
//norealadvice,butjustreflectiveinvocationofthetarget.
if(chain.isEmpty()&&Modifier.isPublic(method.getModifiers())){
//WecanskipcreatingaMethodInvocation:justinvokethetargetdirectly.
//NotethatthefinalinvokermustbeanInvokerInterceptor,soweknow
//itdoesnothingbutareflectiveoperationonthetarget,andnohot
//swappingorfancyproxying.
Object[]argsToUse=AopProxyUtils.adaptArgumentsIfNecessary(method,args);
retVal=methodProxy.invoke(target,argsToUse);
}
else{
//Weneedtocreateamethodinvocation...
retVal=newCglibMethodInvocation(proxy,target,method,args,targetClass,chain,methodProxy).proceed();
}
retVal=processReturnType(proxy,target,method,retVal);
returnretVal;
}
finally{
if(target!=null){
releaseTarget(target);
}
if(setProxyContext){
//Restoreoldproxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

		

通過分析List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)返回的是TransactionInterceptor,利用TransactionInterceptor是如何實(shí)現(xiàn)代理邏輯調(diào)用的?

跟蹤new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

發(fā)現(xiàn)最終是調(diào)用TransactionInterceptor#invoke方法,并且把CglibMethodInvocation注入到invoke方法中,從上面可以看到CglibMethodInvocation是包裝了目標(biāo)對象的方法調(diào)用的所有必須信息,因此,在TransactionInterceptor#invoke里面也是可以調(diào)用目標(biāo)方法的,并且還可以實(shí)現(xiàn)類似@Around的邏輯,在目標(biāo)方法調(diào)用前后繼續(xù)注入一些其他邏輯,比如事務(wù)管理邏輯。

TransactionInterceptor–最終事務(wù)管理者

下面看代碼。

  • TransactionInterceptor#invoke
@Override
publicObjectinvoke(finalMethodInvocationinvocation)throwsThrowable{
//Workoutthetargetclass:maybe{@codenull}.
//TheTransactionAttributeSourceshouldbepassedthetargetclass
//aswellasthemethod,whichmaybefromaninterface.
ClasstargetClass=(invocation.getThis()!=null?AopUtils.getTargetClass(invocation.getThis()):null);

//AdapttoTransactionAspectSupport'sinvokeWithinTransaction...
returninvokeWithinTransaction(invocation.getMethod(),targetClass,newInvocationCallback(){
@Override
publicObjectproceedWithInvocation()throwsThrowable{
returninvocation.proceed();
}
});
}

繼續(xù)跟蹤invokeWithinTransaction,下面的代碼中其實(shí)就可以看出一些邏輯端倪,就是我們猜想的實(shí)現(xiàn)方式,事務(wù)管理。

protectedObjectinvokeWithinTransaction(Methodmethod,ClasstargetClass,finalInvocationCallbackinvocation)
throwsThrowable{

//Ifthetransactionattributeisnull,themethodisnon-transactional.
finalTransactionAttributetxAttr=getTransactionAttributeSource().getTransactionAttribute(method,targetClass);
finalPlatformTransactionManagertm=determineTransactionManager(txAttr);
finalStringjoinpointIdentification=methodIdentification(method,targetClass);

if(txAttr==null||!(tminstanceofCallbackPreferringPlatformTransactionManager)){
//StandardtransactiondemarcationwithgetTransactionandcommit/rollbackcalls.
//開啟事務(wù)
TransactionInfotxInfo=createTransactionIfNecessary(tm,txAttr,joinpointIdentification);
ObjectretVal=null;
try{
//Thisisanaroundadvice:Invokethenextinterceptorinthechain.
//Thiswillnormallyresultinatargetobjectbeinginvoked.
//方法調(diào)用
retVal=invocation.proceedWithInvocation();
}
catch(Throwableex){
//targetinvocationexception
//回滾事務(wù)
completeTransactionAfterThrowing(txInfo,ex);
throwex;
}
finally{
cleanupTransactionInfo(txInfo);
}
//提交事務(wù)
commitTransactionAfterReturning(txInfo);
returnretVal;
}

else{
//It'saCallbackPreferringPlatformTransactionManager:passaTransactionCallbackin.
try{
Objectresult=((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr,
newTransactionCallback(){
@Override
publicObjectdoInTransaction(TransactionStatusstatus){
TransactionInfotxInfo=prepareTransactionInfo(tm,txAttr,joinpointIdentification,status);
try{
returninvocation.proceedWithInvocation();
}
catch(Throwableex){
if(txAttr.rollbackOn(ex)){
//ARuntimeException:willleadtoarollback.
if(exinstanceofRuntimeException){
throw(RuntimeException)ex;
}
else{
thrownewThrowableHolderException(ex);
}
}
else{
//Anormalreturnvalue:willleadtoacommit.
returnnewThrowableHolder(ex);
}
}
finally{
cleanupTransactionInfo(txInfo);
}
}
});

//Checkresult:ItmightindicateaThrowabletorethrow.
if(resultinstanceofThrowableHolder){
throw((ThrowableHolder)result).getThrowable();
}
else{
returnresult;
}
}
catch(ThrowableHolderExceptionex){
throwex.getCause();
}
}
}

		

總結(jié)

最終可以總結(jié)一下整個(gè)流程,跟開始的猜想對照。

來源:blog.csdn.net/qq_20597727/article/details/84868035

責(zé)任編輯:haq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4967

    瀏覽量

    73948
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    341

    瀏覽量

    15933

原文標(biāo)題:Spring的@Transactional如何實(shí)現(xiàn)的(必考)

文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    結(jié)構(gòu)體聲明與定義

    int year;//入學(xué)年份,用無符號(hào)整數(shù)表示 unsigned int years;//學(xué)制,用無符號(hào)整數(shù)表示 }; int main(void) { /** *在main函數(shù)聲明結(jié)構(gòu)體
    發(fā)表于 12-11 07:52

    發(fā)布元服務(wù)配置隱私聲明

    元服務(wù)必須先使用AGC的隱私聲明托管服務(wù)生成自己的隱私聲明,才能在版本信息頁面選擇到。詳細(xì)內(nèi)容參見配置隱私聲明(元服務(wù))和配置用戶協(xié)議。 登錄AppGallery Connect,點(diǎn)擊“APP與元
    發(fā)表于 11-25 11:24

    聞泰科技關(guān)于荷蘭經(jīng)濟(jì)部暫停行政令的聲明

    》對安世下達(dá)的行政令”的聲明。作為安世半導(dǎo)體的唯一控股股東,聞泰科技對此高度重視,現(xiàn)就相關(guān)事宜作出如下回應(yīng):? 一、我司對荷蘭經(jīng)濟(jì)部決定的立場 我司注意到荷蘭經(jīng)濟(jì)大臣的上述聲明是在中國商務(wù)部與荷蘭經(jīng)濟(jì)部磋商后發(fā)表的,我司衷心感謝
    的頭像 發(fā)表于 11-24 09:21 ?584次閱讀

    一文了解3C認(rèn)證自我聲明制度

    一、什么是3C認(rèn)證自我聲明3C認(rèn)證自我聲明(CCCSelf-Declaration),是國家市場監(jiān)督管理總局自2019年起推行的新型管理方式。它允許部分低風(fēng)險(xiǎn)產(chǎn)品企業(yè)不再通過第三方認(rèn)證機(jī)構(gòu)發(fā)證,而是
    的頭像 發(fā)表于 11-11 11:58 ?1124次閱讀
    一文了解3C認(rèn)證自我<b class='flag-5'>聲明</b>制度

    并發(fā)丟數(shù)據(jù)深度剖析:MySQL鎖機(jī)制與事務(wù)實(shí)戰(zhàn)踩坑及解決方案

    1、理論來源于實(shí)踐 現(xiàn)象 :于2025-08-13 21:45:35,事實(shí)邏輯表將自身的指標(biāo)與維度同步到原子服務(wù)的實(shí)現(xiàn)時(shí),出現(xiàn)同步過來的指標(biāo)與維度丟失。 核心原因 :兩次重復(fù)的事實(shí)邏輯表同步時(shí)間非常
    的頭像 發(fā)表于 11-10 19:00 ?588次閱讀
    并發(fā)丟數(shù)據(jù)深度剖析:MySQL鎖機(jī)制與<b class='flag-5'>事務(wù)實(shí)</b>戰(zhàn)踩坑及解決方案

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)28: TLP 事務(wù)處理程序的執(zhí)行流程

    最小橋設(shè)備模型的每個(gè)端口的輸入端對接一個(gè) TLP事務(wù)處理程序, 該程序負(fù)責(zé)將接收到的 TLP 事務(wù)進(jìn)行解析和路由轉(zhuǎn)發(fā)。
    的頭像 發(fā)表于 09-23 09:13 ?1065次閱讀
    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)28: TLP <b class='flag-5'>事務(wù)</b>處理程序的執(zhí)行流程

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)28: TLP 事務(wù)處 理程序的執(zhí)行流程

    的上游端口時(shí), 該響應(yīng)類型事務(wù)需要根據(jù)事務(wù)的請求 ID字段與配置空間封裝類的相關(guān)字段進(jìn)行比較, 實(shí)現(xiàn)基于 ID 的路由; 如果對應(yīng)接收端
    發(fā)表于 09-21 08:51

    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)25:UVM驗(yàn)證平臺(tái)

    NVMe over PCIe采用 AXI4-Lite 接口、AXI4 接口和 PCIe3.0X4 接口,其中AXI4-Lite 和 AXI4 總線接口均可抽象為總線事務(wù),而 PCIe 接口信號(hào)可被
    的頭像 發(fā)表于 08-04 16:52 ?804次閱讀
    NVMe高速傳輸之?dāng)[脫XDMA設(shè)計(jì)25:UVM驗(yàn)證平臺(tái)

    Spring攔截器:你的請求休想逃過我的五指山!

    Spring框架,攔截器(Interceptor)是一種強(qiáng)大的機(jī)制,它允許開發(fā)者在請求處理的不同階段插入自定義邏輯。WebApplicationContext作為Spring Web應(yīng)用的上下文容器,為攔截器的配置和管理提供
    的頭像 發(fā)表于 07-26 11:25 ?685次閱讀
    <b class='flag-5'>Spring</b>攔截器:你的請求休想逃過我的五指山!

    如何部署流媒體服務(wù)實(shí)現(xiàn)監(jiān)控功能--基于米爾TI AM62x開發(fā)板

    本文將介紹基于米爾電子MYD-YM62X開發(fā)板(米爾基于TIAM62開發(fā)板)的部署流媒體服務(wù)實(shí)現(xiàn)監(jiān)控功能方案的開發(fā)測試。摘自優(yōu)秀創(chuàng)作者-HonestQiao米爾-TIAM62x開發(fā)板除了可以用官方
    的頭像 發(fā)表于 07-03 08:03 ?2914次閱讀
    如何部署流媒體服<b class='flag-5'>務(wù)實(shí)現(xiàn)</b>監(jiān)控功能--基于米爾TI AM62x開發(fā)板

    嵌入單片機(jī)在電機(jī)控制系統(tǒng)的應(yīng)用

    有效提升電機(jī)控制系統(tǒng)的性能,這也是建立高速實(shí)時(shí)電機(jī)控制系統(tǒng)的前提。 純分享帖,需要者可點(diǎn)擊附件免費(fèi)獲取完整資料~~~*附件:嵌入單片機(jī)在電機(jī)控制系統(tǒng)的應(yīng)用.pdf【免責(zé)聲明】本文系網(wǎng)絡(luò)轉(zhuǎn)載,版權(quán)歸原作者所有。本文所用視頻、圖
    發(fā)表于 06-11 15:07

    如何將一個(gè)FA模型開發(fā)的聲明范式應(yīng)用切換到Stage模型

    模型切換概述 本文介紹如何將一個(gè)FA模型開發(fā)的聲明范式應(yīng)用切換到Stage模型,您需要完成如下動(dòng)作: 工程切換:新建一個(gè)Stage模型的應(yīng)用工程。 配置文件切換:config.json切換
    發(fā)表于 06-04 06:22

    nvme IP開發(fā)之PCIe上

    所示。 圖2PCIe層次結(jié)構(gòu) 事務(wù)層定義了PCIe總線事務(wù),是PCIe總線層次結(jié)構(gòu)的最高層。事務(wù)層采用傳輸層報(bào)文(Transaction Layer Packet,TLP)
    發(fā)表于 05-17 14:54

    聯(lián)創(chuàng)電子公司律師事務(wù)部獲省司法廳批準(zhǔn)設(shè)立

    近日,江西省司法廳正式批準(zhǔn)聯(lián)創(chuàng)電子設(shè)立公司律師事務(wù)部,聯(lián)創(chuàng)電子由此成為江西首家獲批設(shè)立公司律師事務(wù)部的民營上市公司,這標(biāo)志著公司在依法治企方面邁出了堅(jiān)實(shí)步伐,開啟了新的發(fā)展階段。 公司律師事務(wù)部由
    的頭像 發(fā)表于 04-28 11:23 ?1319次閱讀

    白皮書:在HMI應(yīng)用實(shí)現(xiàn)高精度電容觸摸傳感器

    在HMI 應(yīng)用實(shí)現(xiàn)高精度電容觸摸傳感器
    的頭像 發(fā)表于 03-17 16:46 ?2013次閱讀
    白皮書:在HMI應(yīng)用<b class='flag-5'>中</b><b class='flag-5'>實(shí)現(xiàn)</b>高精度電容<b class='flag-5'>式</b>觸摸傳感器