2.4.1 基本的なアプリケーションのエラー処理

データベースアクセス中のエラーは,C++の例外処理に通知されます。このため,例外処理の中でエラーコードを判断し,エラー後の処理を決定します。

アプリケーションの構造は,さまざまな構造が考えられますが,ここでは,メインの処理,データベースとの接続処理,データベースアクセス処理が分離されているという前提で,エラー処理を説明します。

デッドロックエラーの場合
まず,仕掛り中のトランザクションをロールバックします。その後,時間をおいてリトライして,同様のエラーが何度も起こる場合はアプリケーションの処理を中止します。
パスワード不正,アクセス権限不足の場合
アプリケーションからエラーメッセージを出力して終了します。
<この項の構成>
(1) メイン処理
(2) データベース接続処理
(3) データベースアクセス処理

(1) メイン処理

メイン処理では,外部から入力したユーザIDとパスワードをデータベース接続関数へ渡し,次にデータベースアクセス関数を呼び出すものとします。

#define LockError -20001
#define DeadLock  -20002
#define UIDPwdInv -20003
////////////////////////////////////////////////////////////
/// メイン処理
main(int argc, char** argv)
{
  retry=10;
      .....
ユーザIDとパスワード入力
データベース接続関数呼び出し
while(retry > 0){
    try{
    データベースアクセス関数呼び出し
    }
    catch(DBSQLCA e) {
      if (e.e_USERCODE == DeadLock) {
        // デッドロックエラー
        pDB1->Rollback();
        cout << e.e_USERERROR << endl;
        cout << "3秒待ってリトライします" << endl;
        SLEEP(3);
        retry--;
      } else {
        retry = 0;
      }
    }
  }
}

(2) データベース接続処理

メイン関数から渡されたユーザIDとパスワードが正しくなかった場合,アプリケーションからエラーメッセージを出力し,接続を中止します。

////////////////////////////////////////////////////////////
/// データベース接続処理
.....
  try{
  //データベース接続処理
  }
  catch(DBSQLCA e)
  {
    if (e.e_USERCODE == UIDPwdInv )
    {
      // USERID/Password不正
      cout << e.e_USERERROR << endl;
      cout << "接続に失敗しました。
         ユーザID又はパスワードが正しくありません。"<< endl;
    } else {
      .....
    }
  }

(3) データベースアクセス処理

データベースアクセス処理中のエラーは,catchにスローされるので,e_USERCODEに設定されたエラーコードを判定します。データベースアクセスで判断するエラーで,デッドロックが発生した場合は,ロールバックしてロックを解除し,デッドロックを回避します。また,その後,複数回リトライしても同様のエラーが起こる場合は,アプリケーションを終了させます。

//////////////////////////////////////////////////////////////
// データベースアクセス処理
try{
     .....
     // 一つ目のテーブルをロック
     pRs1->Execute("SELECT IN,F_NAME FROM TEST",LOCK_OPT_WAIT);
     pRs1->open();
     // 二つ目のテーブルをロック
     pRs2->Execute("SELECT IN,F_COUNTRY FROM TEST2",LOCK_OPT_WAIT);
     pRs2->open();
  }
  catch(DBSQLCA e) {
    switch (e.e_USERCODE) {
      case DeadLock:    // デッドロックエラー
          throw e;
      case .....   :    // その他のエラー処理
          throw ....;
    }
  }
}