隨筆 - 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 閱讀(601) 評論(0)  編輯  收藏 所屬分類: J2EE
          主站蜘蛛池模板: 芦山县| 南投市| 塔城市| 水城县| 黄骅市| 武定县| 贵州省| 奇台县| 蓬溪县| 四川省| 策勒县| 新平| 广西| 楚雄市| 沅江市| 彭山县| 新野县| 榆树市| 翼城县| 板桥市| 安图县| 舒兰市| 米脂县| 牡丹江市| 宿州市| 商南县| 桐庐县| 商洛市| 翁牛特旗| 德阳市| 阿克陶县| 信丰县| 定安县| 紫云| 双城市| 乌什县| 柯坪县| 永州市| 浏阳市| 吴川市| 怀仁县|