Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
小林 真治
SQL Developer Support Escalation Engineer
今回は、SQL Server Integration Services (SQL2005/2008/2008R2/2012) において、パッケージの TransactionLevel を required とした際に、パッケージの動作が停止しているように見える現象について解説します。
問題
下記の構成の SQL Server Integration Services (以下 SSIS) のパッケージを作成し、実行すると SSIS パッケージの動作が停止しているように見える。
- SQL Server 上のテーブルを転送先としている。
- SQL 実行タスクで転送先のテーブルデータを truncate クエリを利用して削除する。
- データフロータスクにて、上記クエリでデータを削除したテーブルにデータを転送する。
- SQL 実行タスク >>> データフロータスクのフローで結ばれている。
- SSIS パッケージの TransactionOption オプションとして Required を選択している。
原因
上記構成の SSIS パッケージを実行すると、 Truncate クエリにより後続の処理がブロッキングされます。この結果、SSIS パッケージの動作が停止しているように見えます。
詳細
まず、SQL 実行タスク - データフロータスクのフローで SSIS パッケージを実行した際の内部的について説明します。
該当フローを実行した場合、内部的には下記の処理が実施されます。また、この処理を実施するために、対象の SQL Server は必要なロックを獲得します。
a). SQL 実行タスクのために、 Truncate クエリが転送先テーブルに対して実行される(この時、SQL Server 上の該当テーブルは スキーマ修正共有ロック(LCK_M_SCH_S) というロックが保持されます)。
b). データフロータスクの実行のために、転送元、転送先のテーブルのスキーマ情報が取得される(この時、SQL Server 上の該当テーブルのスキーマを取得するためにスキーマ情報へのロックを獲得します)。
c). データフロータスク内で定義されたテーブルに対して Insert Bulk クエリによるデータ転送が実行される。
次に、SSIS パッケージの TransactionOption を Required にした際の動作について説明します。
SSIS パッケージの TransactionOption を Required にした場合、 SSIS は、分散トランザクションを利用して、パッケージのトランザクションの一貫性を管理します。
このため、SSIS パッケージから SQL Server に対して実行されるクエリは、分散トランザクション コーディネータ(MSDTC) を介して実行される動作となります。
このような前提があった上で、上記フローを実行する SSIS パッケージの TransactionOption を Required とすると、パッケージの処理が終了するまで、 MSDTC によって、上記 a). の転送先テーブルのスキーマ共有ロックが保持され続ける状態となり、後続のスキーマ情報を取得するためのロック獲得の処理 b). が、ブロックされます。
後続のスキーマ情報を取得するためには、 a). の Truncate クエリがコミットされることが条件となりますが、このクエリはパッケージの終了までコミットされませんので、結果として SSIS パッケージは動作を停止しているかのような状態となります。
対処策
この現象に回避するために下記の対処を検討します。
1). Truncate クエリではなく DELETE クエリを利用する。
------------------------------------------------------------------------------------------------------------
DELETE クエリは、該当テーブルに対するスキーマロックを獲得しません。このため、後続のスキーマ情報を取得する b) の処理が、ブロックされることを回避できます。
2). SSIS パッケージの TransactionOption を supported とする。
------------------------------------------------------------------------------------------------------------
SSIS パッケージの TransactionOption を supported とすることで、 Truncate クエリの実行完了時にトランザクションがコミットされますので、その時点でロックは解放され、後続の処理をブロックすることを防げます。