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

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

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

    kapok

    垃圾桶,嘿嘿,我藏的這么深你們還能找到啊,真牛!

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      455 隨筆 :: 0 文章 :: 76 評論 :: 0 Trackbacks

    spring自建事務(wù)管理模塊。而且這個事務(wù)管理是一個抽象設(shè)計,可以應(yīng)用到很多場合,包括普通的DataSource,jta,jms和hibernate上。

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

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

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

    比如

    HibernateTransactionManager
    java代碼: 

    protected void doCommit(DefaultTransactionStatus status) {
                    HibernateTransactionObject txObject = (HibernateTransactionObject) status.getTransaction();
                    if (status.isDebug()) {
                            logger.debug("Committing Hibernate transaction on session [" +
                                            txObject.getSessionHolder().getSession() + "]");
                    }
                    try {
                            txObject.getSessionHolder().getTransaction().commit();
                    }
    ...

            }
     

     

    jdbc 的DataSourceTransactionManager
    java代碼: 

    protected void doCommit(DefaultTransactionStatus status) {
                    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
                    Connection con = txObject.getConnectionHolder().getConnection();
                    if (status.isDebug()) {
                            logger.debug("Committing JDBC transaction on connection [" + con + "]");
                    }
                    try {
                            con.commit();
                    }
                    ...
            }
     

     

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

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

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

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

    先來看看spring reference中的一段代碼
    java代碼: 

    DefaultTransactionDefinition def = new DefaultTransactionDefinition()
    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

    TransactionStatus status = transactionManager.getTransaction(def);

    try {
        // execute your business logic here
    } catch (MyException ex) {
        transactionManager.rollback(status);
        throw ex;
    }
    transactionManager.commit(status);
     

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

    java代碼: 

    public Object execute(TransactionCallback action) throws TransactionException {
                    TransactionStatus status = this.transactionManager.getTransaction(this);
                    Object result = null;
                    try {
                            result = action.doInTransaction(status);
                    }
                    catch (RuntimeException ex) {
                            // transactional code threw application exception -> rollback
                            rollbackOnException(status, ex);
                            throw ex;
                    }
                    catch (Error err) {
                            // transactional code threw error -> rollback
                            rollbackOnException(status, err);
                            throw err;
                    }
                    this.transactionManager.commit(status);
                    return result;
            }
     


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

    private void rollbackOnException(TransactionStatus status, Throwable ex) throws TransactionException {
                    if (logger.isDebugEnabled()) {
                            logger.debug("Initiating transaction rollback on application exception", ex);
                    }
                    try {
                            this.transactionManager.rollback(status);
                    }
                    catch (RuntimeException ex2) {
                            logger.error("Application exception overridden by rollback exception", ex);
                            throw ex2;
                    }
                    catch (Error err) {
                            logger.error("Application exception overridden by rollback error", ex);
                            throw err;
                    }
            }
     

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

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

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

    java代碼: 

    public Object invoke(MethodInvocation invocation) throws Throwable {
                    // Work out the target class: may be null.
                    // The TransactionAttributeSource should be passed the target class
                    // as well as the method, which may be from an interface
                    Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;
                   
                    // Create transaction if necessary
                    TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);

                    Object retVal = null;
                    try {
                            // This is an around advice.
                            // Invoke the next interceptor in the chain.
                            // This will normally result in a target object being invoked.
                            retVal = invocation.proceed();
                    }
                    catch (Throwable ex) {
                            // target invocation exception
                            doCloseTransactionAfterThrowing(txInfo, ex);
                            throw ex;
                    }
                    finally {
                            doFinally(txInfo);
                    }
                    doCommitTransactionAfterReturning(txInfo);

                    return retVal;
            }
     

    萬變不離其宗。

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

    posted on 2005-03-16 11:50 笨笨 閱讀(674) 評論(0)  編輯  收藏 所屬分類: HibernateAndSpringALL
    主站蜘蛛池模板: 久久亚洲精品成人无码网站| 亚洲av无码专区青青草原| 永久免费AV无码国产网站| 国产99视频免费精品是看6| 免费国产va在线观看| 国产免费啪嗒啪嗒视频看看| 成人免费777777被爆出| 四虎亚洲精品高清在线观看| 亚洲线精品一区二区三区影音先锋 | 亚洲国产精品无码成人片久久 | 亚洲AV无码1区2区久久| 毛片A级毛片免费播放| a在线视频免费观看| 亚洲国产精品无码AAA片| 成人毛片免费观看| 午夜免费福利片观看| 老司机亚洲精品影院在线观看| 亚洲男人av香蕉爽爽爽爽| 最近高清中文字幕无吗免费看| 一区二区三区AV高清免费波多| 亚洲国产精品日韩在线| 在线日韩日本国产亚洲| 成人免费在线视频| 精品一区二区三区无码免费视频| 四虎国产精品成人免费久久| 亚洲一级毛片在线观| 猫咪社区免费资源在线观看| 三级网站免费观看| 亚洲人成网站日本片| 亚洲中久无码永久在线观看同| 手机看片久久国产免费| 日本免费人成在线网站| a级毛片免费全部播放| 野花视频在线官网免费1| 亚洲综合在线一区二区三区| 亚洲乱码中文字幕综合234| 成人奭片免费观看| www视频在线观看免费| 久久青草91免费观看| 久久久久免费视频| 色哟哟国产精品免费观看|