本人が遭遇したspring事務のUexpected RollbackException異常解決ノート

2318 ワード

本人は最近spring事務管理を使う過程で次のような異常が発生しました.500元をサービス先に投げ出して、フロントエンドの友達に文句を言われました.前と後で30分ぐらい繰り返して解決しました.今日はこのミスを繰り返さないようにメモを取ります.はい、間違いはこうです.
org.springframe expected RollbackException:Transaction rolled back because it has been marked as rollback-only
後になって気づいたのですが、私のこの問題はsshやssmのような枠組みの中で、実は一定の普遍性を持っています.上記の異常は主に以下のjavaダミーコードで説明されるシーンに現れます.
sshやssmなどのフレームワークを統合したプロジェクトでは、通常service層の事務はspringによって代行される.サービス層の方法に異常が発生したり、投げ出したりすると、事務がロールバックして提出できなくなります.通常、私達のプロジェクトにはグローバルな異常処理メカニズムが設けられています.異常が発生すると、グローバルな異常処理メカニズムが統一されます.
しかし、いくつかの特殊なシーンでは、例えば、次のサービス層serviceAは、別のサービス層serviceBの方法methodBを呼び出す方法を持っています.methodAの実際の実行過程において、methodBが例外を投げる可能性があるが、methodBが正常に実行されているかどうかは、methodAの実行に影響を与えない場合、通常はmethodAがこの異常を積極的に捕獲する必要がある.この異常がmethodAから積極的に捕獲された場合、methodAの他のコードが異常を出さない限り、methodAは例外を出さない.methodAが異常を出さないなら、道理でmethodAに作用する事務は正常に提出できるはずですよね.しかし、実際には、一旦methodBが例外を出すと、methodAの他のコードが正しく実行されているかどうかにかかわらず、全体のトランザクションは提出できません.
 serviceA.methodA()
 {  
       doSomethingA();  

      try {  
             serviceB.methodB{}; //           , doSetRollbackOnly(status);  
          }
           catch {  
                //      commit ,          ,              
               }         

       doSomethingB();  

  }   
上記の異常が発生したのは、自分がspring事務の仕組みをよく理解していなかったからです.上記のmethodAが実行を呼び出された場合、springトランザクションによってエージェントされている二つの点があります.つまり、serviceA.methodA()とserviceB.methodB()の2つの方法では、異常がある限りロールバックします.上記のシーンにはビジネスネストがありますが、methodAに異常があると直接にロールバックしますが、methodBに異常があるのはステータスだけをマークしてロールバックが必要です.最終的にはmethodAでロールバックします.上記のシーンではmethodBに異常があることをロールバックと表記しましたが、methodAに捕獲されましたので、ロールバックしないで最後までcommtを実行しました.commtではスプリングはロールバックフラグがあると判断し、ロールバックフラグがあることを検出するとロールバックし、UnxpectedRollbackException異常をスローします.
上记の事务に対して提出できない解决方法について、私は今二つの処理方法をまとめました.道を通って见たことがあります.また何かいい解决方法があれば、私にメッセージを残してください.本題に戻ります.本人がまとめたこの二つの解決方法は以下の通りです.
  • serviceB.methodBは事務代理として宣言していません.しかし、serviceB.methodBも他のところで使われることが多く、事務管理が必要です.この時はもう一つの方法を書き換えることができます.しかしこの方法ではデータの整合性に注意しなければならない.
  • は、1と同様に、serviceB.methodBを書き換える方法でもあるが、中には異常を捨てずに、異常をブール値に変換して返し、このリターンブール値は、実行中に異常が発生したかどうかを示すマーカーmethodBに相当する.methodAは、この戻りの状態値に基づいて、後続のコードが継続する必要があるかどうかを判断することができる.このように、上記の異常の発生を回避することもできる.