適用対象:✅ Microsoft Fabric の SQL 分析エンドポイントおよびウェアハウス
SQL Server での動作と同様に、トランザクションを使用すると、読み取りと書き込みのクエリのコミットまたはロールバックを制御できます。
Fabric Data Warehouse では、ACID に準拠したトランザクションがサポートされます。 各トランザクションは、原子的で、一貫性があり、分離され、持続性があります (ACID)。 1 つのトランザクション内のすべての操作はアトミックに処理され、すべて成功するか失敗します。 トランザクション内のステートメントが失敗した場合、トランザクション全体がロールバックされます。
明示的なトランザクション
明示的なトランザクションを使用して、ウェアハウスのテーブルに格納されているデータを変更して、変更をグループ化できます。
たとえば、複数のテーブルへの挿入をコミットするか、エラーが発生した場合にはいっさいコミットしないことができます。 3 つのテーブルに影響する発注書の詳細を変更する場合、それらの変更を 1 つのトランザクションにグループ化できます。 つまり、これらのテーブルに対してクエリを実行すると、すべてのテーブルに変更があるか、いっさい変更がないかのどちらかです。 トランザクションは、複数のテーブル間でデータの一貫性を確保する必要がある場合の一般的な方法です。
明示的なトランザクションには、標準の T-SQL (BEGIN TRAN、 COMMIT TRAN、および ROLLBACK TRAN) 構文制御メカニズムを使用できます。 詳細については、「- BEGIN TRANSACTION
- COMMIT TRANSACTION
- ROLLBACK TRANSACTION」を参照してください。
データベース間クエリ トランザクションのサポート
Microsoft Fabric の Warehouse では、 Lakehouse の SQL 分析エンドポイントからの読み取りなど、同じワークスペース内にある複数のウェアハウスにまたがるトランザクションがサポートされています。 例については、「 データベース間の SQL クエリを記述する」を参照してください。
Fabric Data Warehouse のロックとブロックについて
Fabric Data Warehouse では、クエリが 1 つの行または複数の行に触れるかどうかに関係なく、テーブル レベルのロックが使用されます。 次の表に、さまざまな T-SQL 操作に使用されるロックの一覧を示します。
| ステートメントの種類 | 使用されるロック |
|---|---|
| DML | |
| SELECT | Schema-Stability (Sch-S) |
| INSERT | Intent Exclusive (IX) |
| DELETE | インテント・エクスクルーシブ (IX) |
| UPDATE | Intent Exclusive (IX) |
| マージ | インテントエクスクルーシブ (IX) |
| COPY INTO | Intent Exclusive (IX) |
| DDL | |
| テーブルを作成 | スキーマ変更 (Sch-M) |
| ALTER TABLE | スキーマ変更 (Sch-M) |
| DROP TABLE | スキーマ変更 (Sch-M) |
| TRUNCATE TABLE | スキーマ変更 (Sch-M) |
| SELECT としてテーブルを作成する | スキーマ修正 (Sch-M) |
| テーブルを複製として作成 | スキーマの変更 (Schema-Modification) (Sch-M) |
動的管理ビュー (DMV) sys.dm_tran_locks で現在保持されているロックに対 てクエリを実行できます。
ロック、ロックのエスカレーション、およびロックの互換性の詳細については、「 トランザクション ロックと行のバージョン管理ガイド」を参照してください。
スナップショットの分離
Fabric Data Warehouse では、すべてのトランザクションにスナップショット分離が適用されます。 スナップショット分離は、データのトランザクション レベルの整合性を提供する行ベースの分離レベルであり、 tempdb に格納されている行バージョンを使用して更新する行を選択します。 トランザクションでは、トランザクションの開始時に存在するデータ行バージョンが使用されます。 これにより、各トランザクションは、トランザクションの開始時に存在していたデータの一貫性のあるスナップショットで動作します。
スナップショット分離では、トランザクションの開始時のデータベースの状態に基づいて、トランザクション内のクエリに同じバージョンまたはスナップショットが表示されます。 スナップショット分離では、データを変更するトランザクションはデータを読み取るトランザクションをブロックせず、データを読み取るトランザクションはデータを書き込むトランザクションをブロックしません。 このオプティミスティックな非ブロッキング動作により、複雑なトランザクションでデッドロックが発生する可能性も大幅に低下します。
T-SQL を使用して分離レベルを変更すると、クエリの実行時に変更は無視され、スナップショット分離が適用されます。
スナップショットの分離では、書き込み/書き込みまたは更新の競合が発生する可能性があります。詳細については、「 Fabric Data Warehouse での書き込み/書き込みの競合について」を参照してください。
スキーマ ロック
スキーマ ロックにより、トランザクションで行が更新されている間にテーブルのスキーマが変更されるなど、DDL ステートメントでの競合が防止されます。 スキーマの変更や移行などの DDL 操作は、アクティブな読み取りワークロードによってブロックまたはブロックされる可能性があることに注意してください。
- データ定義言語 (DDL) 操作中、データベース エンジンはスキーマ変更 (
Sch-M) ロックを使用します。 ロックが保持されている間、ロックが解除されるまで、Sch-Mロックによってテーブルへの同時アクセスがすべて禁止されます。 - データ操作言語 (DML) 操作中、データベース エンジンはスキーマの安定性 (
Sch-S) ロックを使用します。Sch-Mロックを取得する操作は、Sch-Sロックによってブロックされます。 クエリのコンパイル中も他のトランザクションは引き続き実行されますが、DDL 操作はスキーマへの排他アクセスを取得できるようになるまでブロックされます。 - DDL 操作では、トランザクションの期間中、ターゲット テーブルに関連付けられている
Xやsys.tablesなどのシステム ビューの行に対する排他 (sys.objects) ロックも取得されます。 これにより、SELECTとsys.tablesの同時sys.objectsステートメントがブロックされます。
ブロックを回避するためのベスト プラクティス
- 実行時間の長いトランザクションを避けるか、同時実行アクティビティが少ない期間中またはまったくない期間中にスケジュールします。
- ブロックを最小限に抑えるために、メンテナンス期間中にのみ DDL 操作をスケジュールします。
- 明示的なユーザー トランザクション (
BEGIN TRAN) 内に DDL ステートメントを配置しないでください。 テーブルを変更する実行時間の長いトランザクションは、ユーザー テーブルとシステム カタログ ビュー (SELECTなど) の両方で、他の DML 操作やsys.tablesクエリのブロックの問題を引き起こす可能性があります。 潜在的なロックの競合を監視してトラブルシューティングするには、sys.dm_tran_locksを使用します。 - 倉庫内のロックと競合を監視します。
- sys.dm_tran_locksを使用して現在のロックを検査します。
- Fabric Data Warehouse では、ユーザー定義トランザクション内のいくつかの DDL ステートメントがサポートされていますが、実行時間の長いトランザクションでは推奨されません。 DDL ステートメントは、トランザクション内で同時実行トランザクションをブロックしたり、書き込み/書き込み競合を引き起こしたりする可能性があります。
Fabric Data Warehouse での書き込み競合について理解する
書き込み/書き込み競合は、2 つのトランザクションが同じテーブルを UPDATE、 DELETE、 MERGE、または TRUNCATE しようとしたときに発生する可能性があります。
Fabric Data Warehouse ではテーブル レベルのロックが使用されるため、書き込み/書き込み競合または更新の競合はテーブル レベルで発生する可能性があります。 2 つのトランザクションが同じテーブル内の異なる行を変更しようとすると、競合する可能性があります。
書き込み競合は主に次の2つの場合から発生します。
- ユーザーによるワークロードの競合
- 複数のユーザーまたはプロセスが、同じテーブルを同時に変更します。
- ETL パイプライン、バッチ更新、または重複するトランザクションで発生する可能性があります。
- システムによって引き起こされる競合
- データ圧縮の自動書き換えなどのバックグラウンド システム タスクは、品質が低いファイルを書き換えます。
- これらはユーザー トランザクションと競合する可能性がありますが、 データ圧縮のプリエンプション により、この種類の書き込み/書き込み競合がアクティブに防止されます。
書き込み/書き込み競合が発生した場合、次のようなエラー メッセージが表示されることがあります。
- エラー 24556: 更新の競合によりスナップショット分離トランザクションが中止されました。 スナップショット分離を使用して、データベース '%.*ls' のテーブル '%.*ls' に直接または間接的にアクセスすると、そのテーブル内の行が別の同時実行トランザクションによって削除または更新された場合、更新の競合が発生する可能性があります。 トランザクションを再試行してください。
- エラー 24706: 更新の競合によりスナップショット分離トランザクションが中止されました。 スナップショット分離を使用して、データベース '%.*ls' のテーブル '%.*ls' に直接または間接的にアクセスして、別のトランザクションによって変更または削除された行を更新、削除、または挿入することはできません。 トランザクションを再試行してください。
これらのエラー メッセージが表示された場合、1 つ以上のトランザクションが成功し、1 つ以上の競合するトランザクションが失敗しました。 失敗したトランザクションを再試行してください。
注
MERGEトランザクションで追加のみの変更が発生する場合でも、引き続き書き込み/書き込み競合が発生します。
MERGEトランザクションが他の同時実行 DML トランザクションとは異なる行に影響を与える場合、MERGEがコミットする最初のトランザクションではない場合、このエラーが発生する可能性があります。
書き込み競合を回避するためのベストプラクティス
書き込み競合を防ぐには:
- 同じテーブルに対する同時
UPDATE、DELETE、MERGE操作は避けてください。- マルチステップ トランザクション内の
UPDATE、DELETE、MERGE操作には注意してください。
- マルチステップ トランザクション内の
- すべてのアプリケーションとクエリで再試行ロジックを使用します。
- ストアド プロシージャと ETL パイプラインに再試行ロジックを実装します。
- 一時的な競合を処理するために、パイプラインまたはアプリで遅延を伴う再試行ロジックを追加します。
- 指数バックオフを使用して、一時的なネットワーク中断を悪化させる再試行ストームを回避します。 詳細については、「 再試行パターン」を参照してください。
- Fabric Data Warehouse バックグラウンド データ圧縮サービスとの書き込み/書き込み競合が発生する可能性がありますが、通常は データ圧縮のプリエンプション 機能によって回避されます。
テーブルと Parquet ファイルの制限
テーブル内の 1 つ以上の行を更新する 2 つ以上の同時実行トランザクションによる競合は、トランザクションの最後に評価されます。 最初にコミットするトランザクションは正常に完了し、他のトランザクションはロールバックされ、エラーが返されます。 これらの競合は、個々の Parquet ファイル レベルではなく、テーブル レベルで評価されます。
INSERT ステートメントでは常に新しい Parquet ファイルが作成されます。つまり、他のトランザクションとの競合が少なくなります。ただし、テーブルのスキーマが変更される可能性がある DDL を除きます。
制限事項
- 分散トランザクションは、
BEGIN DISTRIBUTED TRANSACTIONなど、サポートされていません。 -
ALTER TABLEは、明示的なトランザクション内ではサポートされていません。 - 保存ポイントはサポートされていません。
- 名前付きトランザクションはサポートされていません。
- マークされたトランザクションはサポートされていません。
- 現時点では、ウェアハウスでの T-SQL 機能は制限されています。 現在使用できない T-SQL コマンドの一覧については、 Fabric Data Warehouse の T-SQL サーフェス領域を参照してください。
- トランザクションが空のテーブルにデータを挿入し、ロールバック前に SELECT を発行した場合、自動的に生成される統計にはコミットされていないデータが反映され、統計が不正確になる可能性があります。 統計が不正確な場合、最適化されていないクエリ プランと実行時間につながる可能性があります。 大きな INSERT の後に SELECT を使用するトランザクションをロールバックする場合は、SELECT に記載されている列の統計を更新します。