XE7以前でFireDACのMS SQL Serverから返されるデッドロックエラー(1205)の判定

提供: Support
移動先: 案内検索

問題

MS SQL Serverのロックマネージャは、デッドロックを検出すると、クライアントにエラーコード「1205」を返します。MS SQL Serverのデッドロックの検出方法とエラーコードについては、以下の情報を参考ください。

FireDACでは、データ更新時にエラーが発生した場合の処理をTFDConnection.OnErrorイベントなどへ記述し、デッドロックが発生した場合は、EFDDBEngineException.kind=ekRecordLockedで判定できます。EFDDBEngineExceptionの使用例は、以下の通りです。


Delphiの場合

if E is EFDDBEngineException then
 begin
   case EFDDBEngineException(E).Kind of
     ekRecordLocked: 
            //デッドロック時の処理を記述
end;

なお、EFDDBEngineExceptionのKindプロパティで取得できる種類については、以下の情報を参考ください。

本来であれば、デッドロックの判定は上記の方法で行えるのですが、MSSQLServerから返されるエラーコードが「1205」の場合、EFDDBEngineException.kindの値は、「ekRecordLocked」ではなく、「ekOther」になります。これは、FireDACではデータベースから返されるネイテイブのエラーコードによって、エラー種類の判別を行っていますが、エラーコード「1205」に関する判定処理が抜けており、結果としてどのエラーにも属さない「ekOther」になるFireDACの不具合です。

解決

こちらの症状は、XE7で修正されています。

XE7以前のバージョンで改善するには、以下の該当するユニットファイルをご自身のプロジェクトへコピーし、修正してください。修正するソースコード行は、FireDACのバージョンやアップデートによって若干異なりますので、その場合は“ekRecordLocked”のキーワードで該当するファイル内を検索してください。


修正するファイル名(FireDAC.Phys.MSSQL.pas)

case ANativeError of
  1204,
  1205,  // 追加
  1222:
    AKind := ekRecordLocked;