<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    老妖的博客
    現(xiàn)實(shí)的中沒(méi)有幾個(gè)人能夠真為對(duì)方去死,甚至山盟海誓很快就會(huì)在金錢面前變的微不足道,這才是生活。沒(méi)有永遠(yuǎn)的愛(ài),除了你的父母對(duì)你,當(dāng)然也就沒(méi)有永遠(yuǎn)的恨,更沒(méi)有永遠(yuǎn)的痛,時(shí)間是最好的治療大師,它會(huì)很快撫平你心靈上累累的傷痕。很多年以后你想起來(lái)時(shí),那些在你生命中洶涌來(lái)往的人群至多是個(gè)模糊的影子或者毫無(wú)意義的名字
    posts - 105,  comments - 171,  trackbacks - 0

    轉(zhuǎn)自:http://www.javaeye.com/topic/11190
    spring自建事務(wù)管理模塊。而且這個(gè)事務(wù)管理是一個(gè)抽象設(shè)計(jì),可以應(yīng)用到很多場(chǎng)合,包括普通的DataSource,jta,jms和hibernate上。

    要正確使用spring的事務(wù),首先需要了解spring在事務(wù)設(shè)計(jì)上的一些概念
    統(tǒng)觀spring事務(wù),圍繞著兩個(gè)核心PlatformTransactionManager和TransactionStatus

    PlatformTransactionManager直譯過(guò)來(lái)就是平臺(tái)相關(guān)事務(wù),這里的平臺(tái)指的是“事務(wù)源”,包括剛才我說(shuō)的DataSource,jta等等。這些無(wú)一不是一個(gè)事務(wù)源。廣義的說(shuō),凡是可以完成事務(wù)性操作的對(duì)象,都可以設(shè)計(jì)出相對(duì)應(yīng)的PlatformTransactionManager,只要這個(gè)事務(wù)源支持commit,rollback和getTransaction語(yǔ)意。

    查看spring代碼,可以發(fā)現(xiàn)這些manager實(shí)現(xiàn)事務(wù),就是調(diào)用事務(wù)源的事務(wù)操作方法

    比如

    HibernateTransactionManager

    代碼
    1. protected void doCommit(DefaultTransactionStatus status) {   
    2.         HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();   
    3.         if (status.isDebug()) {   
    4.             logger.debug("Committing Hibernate transaction on session [" +   
    5.                     txObject.getSessionHolder().getSession() + "]");   
    6.         }   
    7.         try {   
    8.             txObject.getSessionHolder().getTransaction().commit();   
    9.         }   
    10. ...   
    11.   
    12.     }  

     

    jdbc 的DataSourceTransactionManager

    代碼
    1. protected void doCommit(DefaultTransactionStatus status) {   
    2.         DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();   
    3.         Connection con = txObject.getConnectionHolder().getConnection();   
    4.         if (status.isDebug()) {   
    5.             logger.debug("Committing JDBC transaction on connection [" + con + "]");   
    6.         }   
    7.         try {   
    8.             con.commit();   
    9.         }   
    10.         ...   
    11.     }  

     

    那么PlatformTransactionManager以什么依據(jù)處理事務(wù)呢?
    是TransactionStatus
    查看api發(fā)現(xiàn)這個(gè)接口有三個(gè)方法
    isNewTransaction() ,isRollbackOnly(),setRollbackOnly()
    PlatformTransactionManager就是根據(jù)前兩個(gè)方法決定是否要?jiǎng)?chuàng)建一個(gè)新事務(wù),是要遞交還是回滾。至于第三個(gè)方法是改變事務(wù)當(dāng)前狀態(tài)的,很多地方都要用到,偏偏PlatformTransactionManager自身好像不怎么用,畢竟事務(wù)狀態(tài)的改變是由程序員代碼決定的,不需要一個(gè)manager多管閑事。

    總結(jié)上面所說(shuō)的,spring的事務(wù)由PlatformTransactionManager管理,manager最后調(diào)用事務(wù)源的方法來(lái)實(shí)現(xiàn)一個(gè)事務(wù)過(guò)程。而manager通過(guò)TransactionStatus 來(lái)決定如何實(shí)現(xiàn)。

    接下去說(shuō)spring事務(wù)中的TransactionTemplate和TransactionInterceptor

    TransactionTemplate其實(shí)和spring中其他的template的作用類似,起到化簡(jiǎn)代碼的作用,不要被它那么長(zhǎng)的名字嚇倒了,事實(shí)上這個(gè)template并不是什么非常核心的對(duì)象。如果比較學(xué)究派的,可以去看看template設(shè)計(jì)模式,在此就不再對(duì)此贅述了。
    為什么要有TransactionTemplate?先來(lái)看看如果沒(méi)有TransactionTemplate,我們的代碼該怎么寫

    先來(lái)看看spring reference中的一段代碼

    代碼
    1. DefaultTransactionDefinition def = new DefaultTransactionDefinition()   
    2. def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);   
    3.   
    4. TransactionStatus status = transactionManager.getTransaction(def);   
    5.   
    6. try {   
    7.     // execute your business logic here   
    8. catch (MyException ex) {   
    9.     transactionManager.rollback(status);   
    10.     throw ex;   
    11. }   
    12. transactionManager.commit(status);  

    這是直接使用transactionManager的例子,可以看到真正執(zhí)行business logic 的地方是在try當(dāng)中那段,前后的代碼都是為了完成事務(wù)管理的。如果每個(gè)business logic都要寫上那么一段,我肯定是瘋了。我們翻出TransactionTemplate的代碼看看他怎么化簡(jiǎn)了我們的代碼

     

    代碼
    1. public Object execute(TransactionCallback action) throws TransactionException {   
    2.         TransactionStatus status = this.transactionManager.getTransaction(this);   
    3.         Object result = null;   
    4.         try {   
    5.             result = action.doInTransaction(status);   
    6.         }   
    7.         catch (RuntimeException ex) {   
    8.             // transactional code threw application exception -> rollback   
    9.             rollbackOnException(status, ex);   
    10.             throw ex;   
    11.         }   
    12.         catch (Error err) {   
    13.             // transactional code threw error -> rollback   
    14.             rollbackOnException(status, err);   
    15.             throw err;   
    16.         }   
    17.         this.transactionManager.commit(status);   
    18.         return result;   
    19.     }  

     

    同上面的代碼如出一轍,前后是事務(wù)處理代碼,當(dāng)中那段result = action.doInTransaction(status);是我們的應(yīng)用代碼。至于action是什么,全看各位的需要了。但是有一點(diǎn)要主要,如果利用TransactionTemplate,那么他不管你扔出什么異常都會(huì)回滾事務(wù),但是回滾的是哪個(gè)事務(wù)呢?繼續(xù)挖代碼

    代碼
    1. private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {   
    2.         if (logger.isDebugEnabled()) {   
    3.             logger.debug("Initiating transaction rollback on application exception", ex);   
    4.         }   
    5.         try {   
    6.             this.transactionManager.rollback(status);   
    7.         }   
    8.         catch (RuntimeException ex2) {   
    9.             logger.error("Application exception overridden by rollback exception", ex);   
    10.             throw ex2;   
    11.         }   
    12.         catch (Error err) {   
    13.             logger.error("Application exception overridden by rollback error", ex);   
    14.             throw err;   
    15.         }   
    16.     }  

    真相大白,是對(duì)template所持有的某個(gè)transactionManager進(jìn)行回滾。所以如果你的應(yīng)用代碼用的是事務(wù)源a的一些資源,比如到服務(wù)器a的一個(gè)datasource,但是你的transactionManager管理的是另一些資源,比如服務(wù)器b的一個(gè)datasource,代碼鐵定不會(huì)正常運(yùn)行

     

    特別是在一些多事務(wù)源的程序里,這點(diǎn)千萬(wàn)不能搞錯(cuò)。如果多個(gè)事務(wù)源之間要完成全局事務(wù),還是老老實(shí)實(shí)用分布式事務(wù)管理服務(wù)吧(jta)

    那么TransactionInterceptor是干什么的?這個(gè)是spring 的聲明式事務(wù)的支持方式。因?yàn)橛肨ransactionTemplate要硬編碼,而且調(diào)整事務(wù)策略很麻煩(不是說(shuō)不能調(diào)。舉個(gè)例子原來(lái)程序拋出異常A需要回滾,現(xiàn)在不需要要,我就可以把a(bǔ) catch吃掉。這時(shí)候template就不會(huì)回滾了。但是每次調(diào)整都要重寫編碼。)而用TransactionInterceptor就可以將這些調(diào)整寫在配置中。我們?cè)賮?lái)挖TransactionInterceptor的代碼

    代碼
    1. public Object invoke(MethodInvocation invocation) throws Throwable {   
    2.         // Work out the target class: may be null.   
    3.         // The TransactionAttributeSource should be passed the target class   
    4.         // as well as the method, which may be from an interface   
    5.         Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;   
    6.            
    7.         // Create transaction if necessary   
    8.         TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);   
    9.   
    10.         Object retVal = null;   
    11.         try {   
    12.             // This is an around advice.   
    13.             // Invoke the next interceptor in the chain.   
    14.             // This will normally result in a target object being invoked.   
    15.             retVal = invocation.proceed();   
    16.         }   
    17.         catch (Throwable ex) {   
    18.             // target invocation exception   
    19.             doCloseTransactionAfterThrowing(txInfo, ex);   
    20.             throw ex;   
    21.         }   
    22.         finally {   
    23.             doFinally(txInfo);   
    24.         }   
    25.         doCommitTransactionAfterReturning(txInfo);   
    26.   
    27.         return retVal;   
    28.     }  

    萬(wàn)變不離其宗。

     

    所以使用spring的事務(wù)管理需要作這些事
    1,設(shè)置好事務(wù)源,比如DataSource,hibernate的session。如果有多個(gè)事務(wù)源要考慮他們之間是否有全局事務(wù),如果有,老老實(shí)實(shí)用jta,否則就需要自己寫一個(gè)manager了
    2,設(shè)置manager,根據(jù)你的事務(wù)源選擇對(duì)應(yīng)的PlatformTransactionManager
    3,選擇實(shí)現(xiàn)事物的方式,用template還是interceptor。用template代碼直觀點(diǎn),但是template所管轄的manager和你應(yīng)用代碼所用的事務(wù)源要一致。如果用interceptor千萬(wàn)注意,一定要調(diào)用interceptor那個(gè)bean,而不是原始的那個(gè)target。在壇子上我已經(jīng)看到至少有兩個(gè)朋友說(shuō)spring事物不起作用,從配置和代碼上看都正確,這時(shí)要好好查查,調(diào)用的bean是哪一個(gè)。
    4,這個(gè)是設(shè)計(jì)問(wèn)題了,推薦事務(wù)處于一個(gè)較高層次,比如service上的某個(gè)函數(shù),而底層的dao可以不考慮事務(wù),否則可能會(huì)出現(xiàn)事務(wù)嵌套,增加程序復(fù)雜度。

    posted on 2007-12-24 17:31 老妖 閱讀(2023) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    隨筆分類(48)

    隨筆檔案(104)

    好友鏈接

    我的豆瓣

    積分與排名

    • 積分 - 220777
    • 排名 - 257

    最新評(píng)論

    閱讀排行榜

    主站蜘蛛池模板: 无码日韩人妻AV一区免费l | 在线观看免费毛片| 中文字幕一区二区免费| 亚洲日韩精品国产一区二区三区| 国产亚洲精品国产| 亚洲av麻豆aⅴ无码电影| 成人毛片18女人毛片免费| 在线观看免费av网站| 中文字幕免费观看视频| 亚洲av无码av在线播放| 国产成人精品日本亚洲11| 亚洲一卡2卡三卡4卡有限公司| 国产精品亚洲美女久久久| 日本免费无遮挡吸乳视频电影| 4444www免费看| 无码av免费网站| 青柠影视在线观看免费高清| 污污视频网站免费观看| 亚洲av无码专区首页| 亚洲а∨天堂久久精品9966| 亚洲国产精品久久网午夜| 色噜噜综合亚洲av中文无码| 午夜亚洲AV日韩AV无码大全| 亚洲精品乱码久久久久久蜜桃不卡| 免费午夜爽爽爽WWW视频十八禁| 成人无遮挡毛片免费看| 免费看国产精品3a黄的视频| 久草免费在线观看视频| 1000部拍拍拍18勿入免费视频软件 | 亚洲乱码卡一卡二卡三| 亚洲日产2021三区在线| 亚洲精品美女久久久久| 久久夜色精品国产噜噜噜亚洲AV | 最近免费中文字幕大全免费版视频| 亚洲免费视频一区二区三区| 一级日本高清视频免费观看| 成年免费a级毛片| h片在线观看免费| 国产在线观a免费观看| 国产一级一毛免费黄片| 成全在线观看免费观看大全|