隨筆 - 100  文章 - 50  trackbacks - 0
          <2014年12月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          我收藏的一些文章!

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          框架采用的是spring管理聲明式事務,這幾天業務開發時遇到了點麻煩,記錄下備忘。

           

           場景:在Service類中使用子事務(saveponit)時,當子事務拋出異常后,此異常處理掉不繼續往外拋,spring在提交主事務時會拋出

          org.springframework.transaction.UnexpectedRollbackException: Transaction has been rolled back because it has been marked as rollback

           

           方法調用結構:

                假若有A、B、C三個Service類,其實例對象分別為a、b、c,類分別定義如下:

           

                      A {

                              方法() {                   //propagation="REQUIRED"

            try{

           

                                          b.方法();

             } catch (Exception e) {

                     }

                              }      

             }

           

                      B{

                               savePoint方法() {  //propagation="NESTED"

             c.方法(); //如果這里邊的操作全是普通類(不是Service類)操作,不會有問題。

                               }

                       }

           

           

                      C{

                                方法() {                 //propagation="REQUIRED"

            throw new Exception("出錯");

               }

           

                        }

           

           

             通過調試spring源碼 

                     ......

                     Getting transaction for [A.方法] .....

                     ......

             Creating nested transaction with name [B.savePoint方法]........

             ......

                     Participating in existing transaction

                     Getting transaction for [C.方法]

                     ........

             Participating transaction failed - marking existing transaction as rollback-only

                     //此時,已把主事務標記成了rollback-only

           

                     所以,當在a.方法完成時提交事務時會報Transaction has been rolled back because it has been marked as rollback錯誤。

           

                     認真的您可能會發現,在 org.springframework.transaction.support.AbstractPlatformTransactionManager 中有個叫

          isGlobalRollbackOnParticipationFailure的參數,默認是true.

           

                    源碼中說明:

           

                  Switch this to "false" to let the transaction originator make the rollback decision. If a participating transaction fails with an exception, the caller can still decide to continue with a different path within the transaction. However, note that this will only work as long as all participating resources are capable of continuing towards a transaction commit even after a data access failure: This is generally not the case for a Hibernate Session, for example; neither is it for a sequence of JDBC insert/update/delete operations.

           

                    大意是:如果isGlobalRollbackOnParticipationFailure為false,則會讓主事務決定回滾,如果當遇到exception加入事務失敗時,調用者能繼續在事務內決定是回滾還是繼續。然而,要注意是那樣做僅僅適用于在數據訪問失敗的情況下且只要所有操作事務能提交。

           

                  

              初步解決方案:

          <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="globalRollbackOnParticipationFailure" value="false" /> <!--指定此參數為false-->

          </bean>

           

           

              經測試,此問題暫時得到解決,不知道會不會引起其它問題,至少目前還沒有發現其它異常。您若通過此方案解決之后出現了新的問題請留信回復,我們一起交流,非常感謝!

           

          posted on 2014-12-20 14:23 fly 閱讀(606) 評論(0)  編輯  收藏 所屬分類: J2EE
          主站蜘蛛池模板: 黑水县| 蓬溪县| 民勤县| 筠连县| 惠水县| 通榆县| 青州市| 从江县| 沈阳市| 河津市| 额济纳旗| 奉化市| 六盘水市| 大新县| 西峡县| 眉山市| 吉安县| 万安县| 巨鹿县| 武功县| 洪雅县| 勃利县| 白河县| 万源市| 霍林郭勒市| 武城县| 汤阴县| 应用必备| 綦江县| 滦平县| 鱼台县| 五家渠市| 启东市| 镇安县| 赞皇县| 宁河县| 容城县| 阿克| 北辰区| 青龙| 合水县|