Important
Unity カタログのマネージド デルタ テーブルに書き込むトランザクションは 、パブリック プレビュー段階にあります。
Unity カタログで管理されている Iceberg テーブルに書き込むトランザクションは 、プライベート プレビュー段階にあります。 このプレビューに参加するには、 管理された Iceberg テーブルのプレビュー登録フォームを送信します。
トランザクションを使用すると、複数の SQL ステートメントとテーブル間で操作を調整できます。 すべての変更は同時に成功するか、同時にロールバックされることで、操作とテーブル間のデータの一貫性が確保されます。 トランザクションは、原子性、一貫性、分離性、持続性という ACID の保証を提供します。 「Azure Databricks での ACID 保証とは」を参照してください。 トランザクションは、 ストアド プロシージャ と SQL スクリプト と共に使用して、ミッション クリティカルなウェアハウス ワークロードを構築できます。
トランザクションの例を次に示します。
BEGIN ATOMIC
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
INSERT INTO audit_log VALUES (1, 2, 100, current_timestamp());
END;
3 つのステートメントはすべて同時にコミットされます。 ステートメントが失敗した場合、すべての変更がロールバックされ、Databricks は副作用なしでトランザクションを終了します。
トランザクションの実践的な練習については、「 チュートリアル: テーブル間でトランザクションを調整する」を参照してください。
必要条件
複数のステートメントまたは複数のテーブルにまたがるトランザクションを実行するには:
- 書き込まれるすべてのテーブルは、次の条件を満たす必要があります。
- Unity カタログのマネージド テーブル (Delta または Iceberg) にする
- カタログ管理コミットを有効にする
- サポートされているコンピューティングを使用します。
- 非対話型トランザクションの場合は、Databricks Runtime 18.0 以降を実行している SQL ウェアハウス、サーバーレス コンピューティング、またはクラスターを使用します。
- 対話型トランザクションの場合は、任意の SQL ウェアハウスを使用します。
- 差分共有における共有資産のトランザクションの場合は、Databricks Runtime 18.1 以降を使用します。
トランザクション モード
Azure Databricks では、次の 2 つのトランザクション モードがサポートされています。
| モード | 構文 | コミット | ロールバック | 最適な用途 |
|---|---|---|---|---|
| 非対話型 | ATOMIC 複合ステートメント | 成功時の自動 | エラー時の自動 | 固定シーケンス、スケジュールされたジョブ |
| インタラクティブ | BEGIN TRANSACTION; COMMIT; | 手動 | 手動 | 条件付きロジック, 検証とデバッグ, JDBC, ODBC, PyDBC |
両方のモードの構文、例、使用パターンの詳細については、「 トランザクション モード」を参照してください。
サポートされている操作
トランザクション内で次の操作を使用できます。
| Operation | 説明 |
|---|---|
| SELECT | データのクエリと結果の検証 |
| VALUES 条項 | テスト データまたは定数値を生成する |
| INSERT (すべてのバリアントを含む) | 新しい行を追加する |
| UPDATE | 既存の行を変更する |
COPY INTO |
ファイルから Delta テーブルにデータを読み込む |
| DELETE FROM | 行を削除する |
| MERGE INTO | 挿入、更新、削除を組み合わせたアップサート パターン |
トランザクション内のソースの読み取り
トランザクションは、Unity カタログ テーブル (Delta および Iceberg)、ストリーミング テーブル、ビュー、具体化されたビューから読み取ることができます。 非トランザクション ソースから読み取る場合は、 allow_nontransactional_reads ヒントを使用します。
非トランザクション ソースからの読み取り
次の例に示すように、Parquet ファイル、Avro ファイル、フェデレーション テーブルなどの非トランザクション ソースから JDBC を使用して読み取る場合は、 allow_nontransactional_reads ヒントを使用します。
BEGIN TRANSACTION;
-- Read from a non-transactional Parquet source
INSERT INTO transactional_table
SELECT col1, col2
FROM parquet.`/path/to/data`
WITH (allow_nontransactional_reads = true);
-- Read from a managed Delta table (no hint needed)
INSERT INTO another_table
SELECT * FROM managed_delta_table;
COMMIT;
Warnung
非トランザクション読み取りは繰り返し可能ではありません。 トランザクション中にソース データを同時に変更すると、読み取りの整合性が失われる可能性があります。
トランザクションの分離
トランザクションは、すべてのステートメントで反復可能な読み取りを提供します。 トランザクション内のテーブルにアクセスすると、Azure Databricks は最初のアクセス時にそのテーブルの一貫性のあるスナップショットをキャプチャします。 そのテーブルの後続の読み取りはすべてこのスナップショットを使用するため、他のユーザーが同じテーブルを同時に変更した場合でも読み取りの一貫性が維持されます。
例:
BEGIN TRANSACTION;
-- First access to products table captures snapshot
SELECT * FROM products WHERE product_id = 1001;
-- Another user updates product 1001
-- Still reads the same snapshot (repeatable read)
SELECT * FROM products WHERE product_id = 1001;
COMMIT;
競合の検出とコンカレンシー
Azure Databricks では、オプティミスティック コンカレンシー制御が使用されます。 トランザクションはロックされずに続行され、コミット時に競合が検出されます。 コミットすると、Azure Databricks は、他のトランザクションがトランザクションの開始後に同じデータを変更したかどうかを確認します。 競合が存在する場合、トランザクションは失敗します。 非対話型トランザクションの場合、ロールバックも自動的に行われます。 対話型トランザクションの場合は、 ROLLBACK を明示的に実行して、新しいトランザクションを開始する前にトランザクションの状態をクリアする必要があります。
非対話型トランザクションでは、行レベルのコンカレンシーがサポートされます。 ターゲット テーブルで行 レベルのコンカレンシー が有効になっている場合、2 つのトランザクションで同じデータ ファイル内の異なる行が競合することなく変更される可能性があります。
対話型トランザクションでは、テーブル レベルのコンカレンシーがサポートされます。
競合シナリオ
| シナリオ | 説明 |
|---|---|
| 書き込み競合 | 2 つのトランザクションが同じ行を更新または削除します。 |
| 読み書きの競合 | 別のトランザクションによって変更された行を、あなたのトランザクションが読み取りました。 シリアル化可能な分離にのみ適用されます。 |
| ファントム・リードの競合 | 別のトランザクションが、あなたのトランザクションで読み取られた述語に一致する新しい行を追加しました。 WriteSerializable 分離とシリアル化可能分離の両方に適用されます。 |
| メタデータの競合 | 別のトランザクションによってテーブル のスキーマまたはプロパティが変更されました。 |
トランザクションの分離レベルと競合解決の詳細については、「 トランザクション モード」を参照してください。 Azure Databricks 上の Delta Lake テーブルの分離レベルと書き込みの競合動作については、 Azure Databricks の最適化に関する推奨事項を参照してください。
デルタ ログでのトランザクションの表示方法
成功した各トランザクションは、トランザクション内で実行された個々のステートメントの数に関係なく、テーブルの Delta ログに 1 つのエントリとして表示されます。 これにより、クリーンな監査証跡が提供され、ロールバック操作が簡略化されます。
トランザクション内の個々の操作は、トランザクションのデルタ ログ エントリで JSON メタデータとして使用できます。
エラー処理とロールバック
次の表では、両方のトランザクションの種類でエラーロールバックがどのように発生するかを示します。
| シナリオ | 非対話型トランザクションの動作 | 対話型トランザクションの動作 |
|---|---|---|
| ステートメントのエラー | エラーを発生させるステートメントがあると、すぐに自動ロールバックが発生します。 | セッションがまだアクティブな場合は、 ROLLBACK を明示的に実行して変更を破棄する必要があります。 |
| 失敗した検証ロジックまたはビジネス ルール |
SIGNAL を使って、例外を発生させて自動ロールバックをトリガーします。 |
ROLLBACK を実行して変更を破棄します。 |
| セッション切断 | トランザクションは自動的にロールバックされます。 | トランザクションは自動的にロールバックされます。 |
| Timeout | 合計期間が 48 時間後に自動的にロールバックされます。 | 非アクティブな状態が 10 分後、または合計期間が 48 時間後に自動的にロールバックされます ( 制限事項を参照)。 トランザクションは副作用なしで終了しますが、セッションがまだアクティブな場合は、 ROLLBACK を明示的 に実行してトランザクションの状態をクリアする必要があります。 |
対話型トランザクションの場合は、 ROLLBACK ステートメントを使用して明示的にロールバックできます。 これは、検証ロジックまたはビジネス ルールに基づいて変更を破棄する場合や、セッションがアクティブな状態のままステートメントが失敗した後に破棄する場合に便利です。
ベスト プラクティス
競合を減らし、トランザクションのパフォーマンスを最適化するには、次のプラクティスに従います。
競合を回避する
- トランザクションを短くする: 実行時間の長いトランザクションは競合の可能性を高め、リソースを長く保持します。
- 早期検証: トランザクションの開始時に前提条件を確認して、問題があれば迅速に終了します。
- Databricks では、ほとんどのユース ケースで非対話型トランザクションが推奨されます。非対話型トランザクションでは行レベルのコンカレンシーが使用されます。 非対話型トランザクションを参照してください。
- 競合時の再試行: 競合が発生した場合は、新しいデータを使用してトランザクションを再試行します。
異なるクライアントからのトランザクションを使用する
トランザクションは、さまざまなクライアント インターフェイスで機能します。
-
SQL エディターとノートブック: SQL セルで直接
BEGIN ATOMIC ... END;またはBEGIN TRANSACTION; ... COMMIT;構文を使用するか、Python/Scala ノートブックでspark.sql()を使用します。 トランザクション モードを参照してください。 -
JDBC アプリケーション:
setAutoCommit(false)バージョン 3.0.5 以降で JDBC API メソッド (commit()、rollback()、) を使用します。 「例: トランザクションを使用する」を参照してください。 トランザクション内でサポートされていない JDBC 操作の一覧については、「 サポートされていない JDBC 操作」を参照してください。 - ODBC アプリケーション: Databricks ODBC Driver バージョン 2.10.0 以降を使用します。 トランザクション内でサポートされていない ODBC 操作の一覧については、「 サポートされていない ODBC 操作」を参照してください。
-
Python アプリケーション:
autocommit=Falseで Databricks SQL Connector を使用します。 Databricks SQL Connector for Python を参照してください。 トランザクション内でサポートされていない Python コネクタ操作の一覧については、「 サポートされていない Python コネクタ操作」を参照してください。 - ステートメント実行 API: API 呼び出しを使用して SQL 構文を使用してトランザクションを実行します。 「ステートメント実行 API での使用」を参照してください。
制限事項
複数のテーブルにまたがるトランザクションには、次の制限事項が適用されます。
| 制限事項 | 説明 |
|---|---|
| 対話型トランザクションの競合 | 対話型トランザクション (BEGIN TRANSACTION; ... COMMIT;)は非対話型トランザクションよりも保守的な競合検出を使用し、ターゲット テーブルから読み取らない INSERT 操作を除き、テーブル レベルで競合する可能性があります。 行レベルの競合検出が重要な場合は、非対話型トランザクション (ATOMIC 複合ステートメント) を使用します。 非対話型トランザクションを参照してください。 |
| ターゲットを書き込む |
catalogManaged テーブル機能が有効になっている Unity カタログマネージド Delta テーブルまたは Iceberg テーブルにのみ書き込むことができます。
カタログ管理のコミットを参照してください。 |
| DML 操作のみ | トランザクションでは、 SELECT、 INSERT、 UPDATE、 DELETE、 COPY INTO、および MERGEがサポートされます。 トランザクションの外部で、 CREATE TABLE、 ALTER TABLE、 DROP TABLEなどの DDL 操作を実行します。 |
| メタデータ操作はサポートされていません | メタデータ操作は、プロトコルに関係なく、トランザクション内では機能しません。 これには、Thrift RPC ベースのメタデータ呼び出し (JDBC DatabaseMetaData メソッドや ODBC カタログ関数など)、SQL ベースのコマンド (SHOW TABLES、SHOW DATABASES、DESCRIBE TABLE)、SELECT テーブルまたはシステム テーブルに対するinformation_schemaクエリが含まれます。 トランザクションの外部でメタデータ操作を実行します。 |
COPY INTO 並行 処理 |
COPY INTO コマンドを実行しているトランザクションは、別のCOPY INTO コマンドが同時に実行され、同じテーブルに書き込み、先にコミットされると失敗します。 |
| ストリーミング書き込みがサポートされていません | ストリーミング テーブルへのトランザクション書き込みはサポートされていません。 |
| RLS テーブルと CLM テーブルはサポートされていません | 行フィルターと列マスクを含むテーブルは、トランザクションに参加できません。 |
| テーブルとビューの制限 | トランザクションは、最大 100 個のテーブルとの間で読み取りまたは書き込みを行い、最大 100 個のビューから読み取ることができます。 各テーブルは、トランザクション内で最大 100 個の中間コミットを持つことができます。 |
| タイム トラベルはサポートされていません | トランザクション内で タイム トラベル を使用することはできません。 |
| 無操作タイムアウト | 対話型トランザクションは、非アクティブ状態が 10 分続くとロールバックされます。 トランザクションは副作用なしで終了しますが、セッションがまだアクティブな場合は、 ROLLBACK を明示的 に実行してトランザクションの状態をクリアする必要があります。 |
| 最大期間 | すべてのトランザクションは、合計期間が 48 時間後に自動的にロールバックされます。 対話型トランザクションの場合、トランザクションは副作用なしで終了しますが、セッションがまだアクティブな場合は、ROLLBACK を明示的 に実行して トランザクションの状態をクリアする必要があります。 |
| Delta Sharingの共有テーブルの要件 | デルタ共有のプロバイダーは、受信者がトランザクションを実行できるように、テーブルを共有する必要がありますWITH HISTORY。 受信者は、任意の種類のコンピューティングを使用してトランザクションを実行できます。 |
| Delta Sharing受信者のコンピュート制限 | Azure Databricks 受信者は、共有ビュー、具体化されたビュー、ストリーミング テーブル、Iceberg 以外の外部テーブルでのみトランザクションを実行できます。 プロバイダーと同じ Azure Databricks アカウント内の受信者は、共有コンピューティングまたはサーバーレス コンピューティングを使用する必要があります。 別のアカウントの受信者は、サーバーレス コンピューティングを使用する必要があります。 |
| Delta Sharing ソーステーブルの競合 | 1 つのトランザクション内で、同じソース テーブルを参照する共有ビューと共有テーブルの両方を参照することは、差分共有受信者にはできません。 |