ヘッダーをスキップ
Oracle TimesTen In-Memory Database Java開発者およびリファレンス・ガイド
リリース6.0
B25766-01
  目次へ
目次
索引へ
索引

前へ
前へ
次へ
次へ
 

エラー処理

この項では、TimesTen Javaアプリケーションで発生するエラーの検出、識別および処理について説明します。

TimesTenにより返されるエラーのリストおよびエラーが発生した場合の対処方法については、『Oracle TimesTen In-Memory Database APIおよびSQLリファレンス・ガイド』の警告およびエラーに関する章を参照してください。

内容は次のとおりです。

致命的エラー、致命的でないエラーおよび警告

TimesTenでは、致命的エラー、致命的でないエラーまたは警告が返される場合があります。

致命的エラーおよびリカバリの処理

致命的エラーとは、リカバリするまでデータ・ストアにアクセスできなくなるエラーのことです。致命的エラーが発生すると、すべてのデータ・ストアの接続を切断する必要があります。それ以後の処理は完了されません。致命的エラーは、TimesTenのエラー・コード846および994で示されます。これらのエラーの処理は、標準的なエラーの処理とは異なります。具体的には、コードによってトランザクションをロールバックし、データ・ストアからの接続を切断する必要があります。

致命的エラーが発生した場合、TimesTenは、次の完全なクリーンアップおよびリカバリ・プロシージャを実行します。

致命的ではないエラーの処理

致命的ではないエラーには、一意制約に違反しているINSERTなどの単純なエラーが含まれます。また、一部のアプリケーション障害およびプロセス障害も、致命的ではないエラーに含まれます。

TimesTenでは、致命的ではないエラーも、通常のエラー処理プロセスによって返されます。また、エラーの検出および識別はアプリケーションで行う必要があります。

致命的ではないエラーによってデータ・ストアに影響が出た場合、エラーが返されることがあり、アプリケーションで適切に対処する必要があります。プロセスのクラッシュなどの場合はエラーが返されないため、失敗したプロセスのトランザクションが自動的にロールバックされます。

アプリケーションでは、その処理を変更するか、または障害が発生した1つ以上のトランザクションをロールバックすることによって、致命的ではないエラーに対処できます。詳細は、「失敗したトランザクションのロールバック」を参照してください。

注意: ResultSetStatementPreparedStatementCallableStatementまたはConnection操作でデータ・ストアにエラーが発生する場合は、そのオブジェクトに対してcloseメソッドをコールすることをお薦めします。

警告について

予期しない状態が発生した場合、TimesTenは警告を返します。たとえば、次の状況が発生した場合、TimesTenは警告を発行します。

エラーおよび警告のレポート

コールのたびに返される可能性があるすべてのエラーと警告を確認してレポートする必要があります。これによって、開発およびデバッグの時間および労力が大幅に削減されます。データ・ストアのアクセス時にエラーが1つ以上ある場合は、SQLExceptionオブジェクトが発生し、警告メッセージが1つ以上ある場合は、SQLWarningオブジェクトが発生します。1回のコールで複数のエラーまたは警告(あるいはその両方)が返されることがあるため、アプリケーションでは、返されたSQLExceptionオブジェクトまたはSQLWarningオブジェクトにすべてのエラーまたは警告をレポートする必要があります。

SQLExceptionオブジェクトまたはSQLWarningオブジェクトのリンク連鎖では、複数のエラーまたは警告が返されます。例2.12および例2.13に、すべてのエラーと警告をレポートするために返されたSQLExceptionオブジェクトとSQLWarningオブジェクトのリストを繰り返し実行する方法を示します。

例2.12

このメソッドは、リンクされたSQLExceptionオブジェクトのすべての例外の内容を印刷します。

static int reportSQLExceptions(SQLException ex) 
  { 
    int errCount = 0; 
    if (ex != null) { 
      errStream.println("\n--- SQLException caught ---"); 
      ex.printStackTrace(); 
      while (ex != null) { 
        errStream.println("SQL State:   " + ex.getSQLState()); 
        errStream.println("Message:     " + ex.getMessage()); 
        errStream.println("Error Code: " + ex.getErrorCode()); 
        errCount ++; 
        ex = ex.getNextException(); 
        errStream.println(); 
      } 
    } 
    return errCount; 
  } 
例2.13

このメソッドは、リンクされたSQLWarningオブジェクトのすべての例外の内容を印刷します。

static int reportSQLWarnings(SQLWarning wn) 
{ 
   int warnCount = 0; 
   while (wn != null) { 
      errStream.println("\n--- SQL Warning ---"); 
      errStream.println("SQL State:   " + wn.getSQLState()); 
      errStream.println("Message:     " + wn.getMessage()); 
      errStream.println("Error Code: " + wn.getErrorCode()); 
      // is this a SQLWarning object or a DataTruncation object? 
      if (wn instanceof DataTruncation) { 
         DataTruncation trn = (DataTruncation) wn; 
         errStream.println("Truncation error in column: " + 
            trn.getIndex()); 
      } 
      warnCount++; 
      wn = wn.getNextWarning(); 
      errStream.println(); 
   } 
   return warnCount; 
} 

特定のエラーの検出および対応

特定のSQLの状態またはTimesTenエラー・コードに対応する必要がある場合があります。SQLException.getSQLStateを使用してSQL99 SQL状態エラー文字列を返したり、SQLException.getErrorCodeを使用してTimesTenエラー・コードを返すことができます。例2.14を参照してください。

例2.14

TimesTenのデモでは、デモ・スキーマをロードしてから実行する必要があります。ODBCエラーS0002およびTimesTenエラー907が検出されると、次のcatch文により、デモ・スキーマがロードまたは更新されていないというアラートがユーザーに発行されます。

catch (SQLException ex) { 
  if (ex.getSQLState().equalsIgnoreCase("S0002")) { 
     errStream.println("\nError: The table xyz.customer  
         does not exist.\n\t Please run ttIsql -f input0.dat  
         to initialize the database."); 
  } else if (ex.getErrorCode() == 907) { 
     errStream.println("\nError: Attempting to insert a row 
         with a duplicate primary key.\n\tPlease rerun ttIsql -f 
         input0.dat to reinitialize the database."); 
  }  
 

TimesTenVendorCodeインタフェースを使用すると、番号ではなく名前によって、エラーを検出できます。

次に例を示します。

ex.getErrorCode() == com.timesten.jdbc.TimesTenVendorCode.TT_ERR_KEYEXISTS

これは、次の文と同じです。

ex.getErrorCode() == 907

エラーの名前と番号のマッピングについては、「TimesTenVendorCode」を参照してください。

失敗したトランザクションのロールバック

デッドロックまたはタイムアウトの状態からリカバリする場合など、Connection.rollback()メソッドを使用して明示的にトランザクションをロールバックする場合があります。

次に例を示します。

try { 
  if (con != null && !con.isClosed()) { 
   // Rollback any transactions in case of errors 
     if (retcode != 0) { 
       try { 
         System.out.println("\nEncountered error. 
                              Rolling back transaction"); 
         con.rollback(); 
       } catch (SQLException ex) { 
           reportSQLExceptions(ex); 
         } 
      } 
  System.out.println("\nClosing the connection\n"); 
  con.close(); 
} 
 

SYS.MONITOR表のXACT_ROLLBACKS列は、ロールバックされたトランザクションの数を示します。

トランザクションのロールバックによってリソースが消費され、結果的にトランザクション全体が無駄になってしまいます。不要なロールバックを回避するには、可能なかぎり、競合が発生しないようにアプリケーションを設計(「最適なロック方法の選択」)し、送信前にアプリケーションまたは入力データをチェックしてエラーを検出する必要があります。

注意: アプリケーションがアクティブなトランザクションの途中でクラッシュした場合、このトランザクションは自動的にロールバックされます。