データベースアクセス中のエラーは,C++の例外処理に通知されます。このため,例外処理の中でエラーコードを判断し,エラー後の処理を決定します。
アプリケーションの構造は,さまざまな構造が考えられますが,ここでは,メインの処理,データベースとの接続処理,データベースアクセス処理が分離されているという前提で,エラー処理を説明します。
メイン処理では,外部から入力したユーザ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;
}
}
}
}
メイン関数から渡されたユーザIDとパスワードが正しくなかった場合,アプリケーションからエラーメッセージを出力し,接続を中止します。
////////////////////////////////////////////////////////////
/// データベース接続処理
.....
try{
//データベース接続処理
}
catch(DBSQLCA e)
{
if (e.e_USERCODE == UIDPwdInv )
{
// USERID/Password不正
cout << e.e_USERERROR << endl;
cout << "接続に失敗しました。
ユーザID又はパスワードが正しくありません。"<< endl;
} else {
.....
}
}
データベースアクセス処理中のエラーは,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 ....;
}
}
}