デッドロック時のリトライ機能



このままではデッドロックの問題は解決しそうにないので
DB2にデッドロック時のリトライ機能を検討してみました。

Servlet#service()
  FrontController#doProcess()
    InputAction#doExecute()
      N5BZInputAction#callApplication()
        AppProxy#execute()
          EJBAppProxy#doExecute()
            N5BZEJBAppControllerBase#doExecute()
              NYAZHznDichControllerBean#doExecute() ここでSQLExceptionをキャッチしてるように見える。
                NYAKihonJyouhouDao#hoge()
                  N5BZDBUpdate#execute()

今はアプリケーションのコントローラがSQLExceptionをキャッチして
アプリの例外(AppControllerException)をスローしているように見える

いちばん根っこのトランザクションを起動しているのは
	N5BZInputAction#callApplication()
のように見えるので
このcallApplication()メソッドにデッドロック発生時の
リトライメソッドを追加してしまう。

  boolean retry = true;
  while ( retry ) {
    try {
        //...
        // ビジネスロジック起動。
        //...
    catch( SQLException se ) {
      // とりあえず、デッドロック時(SQL0913N)には-913が返るのでチェックしてリトライする。
      if ( se.getErrorCode() == -913 ) {
        System.out.println("またデッドロックしたよ。");
        N5BZUserTransactionUtil.rollbackTransaction(ut);
        N5BZUserTransactionUtil.beginTransaction(ut);
        retry = true;
      }
    }
    catch( Exception e ) {
        //...
    }
  }

のようにデッドロックの発生時にのみ
トランザクションをロールバックして
アプリケーションを再起動するロジックを加える。

うしろでデッドロックが起きても再起動して
画面には正常な応答を返す仕掛け。

下位のアプリケーションがSQLExceptionを別のアプリケーション例外に丸めてるので
例外の属性からデッドロックで失敗したかどうか区別がつかないといけないことが課題。



2003/07/16 ugya@lycos.com