トランザクション
プレビュー
Unity Catalog で管理される Delta テーブルに書き込むトランザクションは、パブリック プレビュー段階にあります。
Unity Catalog で管理される Iceberg テーブルに書き込むトランザクションは、プライベート プレビュー段階です。このプレビューに参加するには、マネージド Iceberg テーブル プレビュー登録フォームを送信してください。
トランザクションを使用すると、複数の SQL ステートメントとテーブル間で操作を調整できます。すべての変更は同時に成功するか、同時にロールバックされるため、操作とテーブル全体でデータの一貫性が確保されます。トランザクションは、原子性、一貫性、独立性、永続性という ACID 保証を提供します。「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 Catalogマネージドテーブル ( DeltaまたはIceberg )であること
- カタログ管理コミットを有効にする
-
サポートされているコンピュートを使用します。
- 非対話型トランザクション の場合は、 SQLウェアハウス、サーバレスコンピュート、またはDatabricks Runtime 18.0 以降が稼働しているクラスター使用します。
- 対話型トランザクション の場合は、任意のSQLウェアハウスを使用します。
- Delta Sharing 共有アセットのトランザクション の場合は、Databricks Runtime 18.1 以上を使用します。
トランザクションモード
Databricks は 2 つのトランザクション モードをサポートしています。
モード | 構文 | Commit | ロールバック | どのようなタスクにベストなのか |
|---|---|---|---|---|
非インタラクティブ | 成功時に自動 | エラー時に自動 | 固定シーケンス、スケジュールされたジョブ | |
対話型 | 手動 | 手動 | 条件付きロジック、検証とデバッグ、JDBC、ODBC、PyDBC |
両方のモードの詳細な構文、例、および使用パターンについては、 「トランザクション モード」を参照してください。
サポートされている操作
トランザクション内では次の操作を使用できます。
オペレーション | 説明 |
|---|---|
データのクエリと結果の検証 | |
テストデータまたは定数値を生成する | |
INSERT (すべてのバリアントを含む) | 新しい行を追加する |
既存の行を変更する | |
ファイルから Delta テーブルにデータをロードする | |
行を削除 | |
挿入、更新、削除を組み合わせたアップサートパターン |
トランザクション内のソースを読み取る
トランザクションは、 Unity Catalogテーブル ( 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;
非トランザクション読み取りは繰り返し実行できません。トランザクション中にソース データが変更されると、読み取りの一貫性が失われる可能性があります。
トランザクション分離
トランザクションは、すべてのステートメントにわたって繰り返し可能な読み取りを提供します。トランザクションでテーブルにアクセスすると、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;
競合検出と同時実行
Databricks は楽観的同時実行制御を使用します。トランザクションはロックなしで進行し、競合はコミット時に検出されます。コミットすると、Databricks はトランザクションの開始後に他のトランザクションが同じデータを変更したかどうかを確認します。競合が存在する場合、トランザクションは失敗します。非対話型トランザクションの場合、ロールバックも自動的に行われます。対話型トランザクションの場合、新しいトランザクションを開始する前に、 ROLLBACK明示的に実行してトランザクション状態をクリアする必要があります。
非対話型トランザクションは行レベルの同時実行性をサポートします。ターゲット テーブルで行レベルの同時実行が有効になっている場合、2 つのトランザクションが競合することなく同じデータ ファイル内の異なる行を変更できます。
対話型トランザクションはテーブルレベルの同時実行性をサポートします。
競合シナリオ
シナリオ | 説明 |
|---|---|
書き込み競合 | 2 つのトランザクションが同じ行を更新または削除します。 |
書き込みと読み取りの競合 | 別のトランザクションが、トランザクションが読み取った行を変更しました。シリアル化可能な分離にのみ適用されます。 |
ファントムリード競合 | 別のトランザクションが、トランザクションが読み取った述語に一致する新しい行を追加しました。WriteSerializable と Serializable の両方の分離に適用されます。 |
メタデータの競合 | 別のトランザクションによってテーブル スキーマまたはプロパティが変更されました。 |
トランザクションの分離レベルと競合解決の詳細については、 「トランザクション モード」を参照してください。Databricks上のDelta Lakeテーブルの分離レベルと書き込み競合の動作については、 Databricksでの最適化の推奨事項を参照してください。
Deltaでのトランザクションの表示方法
成功した各トランザクションは、トランザクション内で実行される個別のステートメントの数に関係なく、テーブルのDeltaログに 1 つのエントリとして表示されます。 これにより、明確な監査証跡が提供され、ロールバック操作が簡素化されます。
トランザクション内の個々の操作は、トランザクションの Delta ログ エントリ内の JSON メタデータとして利用できます。
エラー処理とロールバック
次の表は、両方のトランザクション タイプでエラー ロールバックがどのように発生するかを示しています。
シナリオ | 非対話型トランザクションの動作 | インタラクティブトランザクションの動作 |
|---|---|---|
ステートメントの失敗 | エラーを発生させるステートメントは、即座に自動ロールバックを引き起こします。 | セッションがまだアクティブな場合は、変更を破棄するために明示的にROLLBACKを実行する必要があります。 |
検証ロジックまたはビジネスルールの失敗 | 例外をスローし、自動ロールバックをトリガーするには、 | 変更を破棄するには、 ROLLBACKを実行します。 |
セッション切断 | トランザクションは自動的にロールバックされます。 | トランザクションは自動的にロールバックされます。 |
タイムアウト | 合計 48 時間経過すると自動的にロールバックされます。 | 10 分間操作が行われなかった場合、または合計 48 時間経過した場合、自動的にロールバックされます (制限事項を参照)。トランザクションは副作用なく終了しますが、セッションがまだアクティブな場合は、明示的にROLLBACKを実行してトランザクション状態をクリアする必要があります。 |
対話型トランザクションの場合、 ROLLBACKステートメントを使用して明示的にロールバックできます。これは、検証ロジックまたはビジネス ルールに基づいて変更を破棄する場合や、セッションがアクティブなままステートメントが失敗した場合に役立ちます。
ベストプラクティス
競合を減らし、トランザクションのパフォーマンスを最適化するには、次のプラクティスに従ってください。
衝突を避ける
- トランザクションを短く保つ : トランザクションの実行時間が長いと競合の可能性が高まり、リソースが長く保持されます。
- 早期に検証する : トランザクションの開始時に前提条件をチェックして、早期に失敗できるようにします。
- Databricks では、ほとんどのユース ケースで非対話型トランザクションを推奨しています 。非対話型トランザクションでは、行レベルの同時実行性が使用されます。非対話型トランザクションを参照してください。
- 競合時に再試行 : 競合が発生した場合、新しいデータを使用してトランザクションを再試行します。
異なるクライアントからのトランザクションを使用する
トランザクションはさまざまなクライアント インターフェース間で機能します。
- SQL エディターとノートブック : SQL セルで直接
BEGIN ATOMIC ... END;またはBEGIN TRANSACTION; ... COMMIT;構文を使用するか、Python/Scala ノートブックでspark.sql()を使用します。トランザクション モードを参照してください。 - JDBC アプリケーション : Databricks JDBC ドライバーバージョン 3.0.5 以降で JDBC API メソッド (
setAutoCommit(false)、commit()、rollback()) を使用します。「例: トランザクションの使用」を参照してください。トランザクション内でサポートされていない JDBC 操作のリストについては、 「サポートされていない JDBC 操作」を参照してください。 - ODBC アプリケーション : Databricks ODBC ドライバーバージョン 2.10.0 以降を使用します。トランザクション内でサポートされていない ODBC 操作の一覧については、 「サポートされていない ODBC 操作」を参照してください。
- Python アプリケーション :
autocommit=Falseで Databricks SQL コネクタを使用します。Python 用 Databricks SQL コネクタを参照してください。トランザクション内でサポートされていない Python コネクタ操作のリストについては、 「サポートされていない Python コネクタ操作」を参照してください。 - ステートメント実行 API : API 呼び出しを通じて SQL 構文を使用してトランザクションを実行します。ステートメント実行 API での使用を参照してください。
制限事項
複数のテーブルにまたがるトランザクションには次の制限が適用されます。
制限 | 説明 |
|---|---|
インタラクティブなトランザクションの競合 | 対話型トランザクション ( BEGIN TRANSACTION ; ...コミット;) は、非対話型トランザクションよりも保守的な競合検出を使用し、ターゲット テーブルから読み取らない INSERT 操作を除いて、テーブル レベルで競合が発生する可能性があります。 行レベルの競合検出が重要な場合は、非対話型トランザクション ( ATOMIC 複合ステートメント) を使用します。非対話型トランザクションを参照してください。 |
ターゲットを書き込む |
|
DML操作のみ | トランザクションは、 |
メタデータ操作はサポートされていません | メタデータ操作は、プロトコルに関係なく、トランザクション内では機能しません。これには、Thrift RPC ベースのメタデータ呼び出し ( JDBC |
| 別の |
ストリーミング書き込みはサポートされていません | ストリーミング テーブルへのトランザクション書き込みはサポートされていません。 |
RLS および CLM テーブルはサポートされていません | 行フィルターと列マスクを含むテーブルはトランザクションに参加できません。 |
テーブルとビューの制限 | トランザクションでは、合計最大 100 個のテーブルに対して読み取りまたは書き込みを実行でき、最大 100 個のビューから読み取りを実行できます。各テーブルでは、トランザクション内で最大 100 個の中間コミットを持つことができます。 |
タイムトラベルはサポートされていません | トランザクション内でタイムトラベルを使用することはできません。 |
アイドルタイムアウト | 対話型トランザクションは、10 分間操作が行われないとロールバックされます。トランザクションは副作用なく終了しますが、セッションがまだアクティブな場合は、明示的にROLLBACKを実行してトランザクション状態をクリアする必要があります。 |
最大期間 | すべてのトランザクションは、合計 48 時間経過後に自動的にロールバックされます。対話型トランザクションの場合、トランザクションは副作用なしで終了しますが、セッションがまだアクティブな場合は、明示的にROLLBACKを実行してトランザクション状態をクリアする必要があります。 |
Delta Sharing共有テーブル要件 | Delta Sharingプロバイダーは、受信者がテーブル |
Delta Sharing受信者コンピュート制限 | Databricks受信者は、共有ビュー、マテリアライズドビュー、ストリーミング テーブル、および非 Iceberg フォーリン テーブルでのみトランザクションを実行できます。 プロバイダーと同じDatabricksアカウントの受信者は、共有またはサーバーレス コンピュートを使用する必要があります。 別のアカウントの受信者はサーバレスコンピュートを使用する必要があります。 |
Delta Sharingソーステーブルの競合 | Delta Sharing受信者は、単一のトランザクション内で同じソース テーブルを参照する共有ビューと共有テーブルを参照することはできません。 |