Transactions

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;

インタラクティブ

BEGIN TRANSACTION;
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());
COMMIT;

3 つのステートメントはすべて同時にコミットされます。 ステートメントが失敗した場合、すべての変更がロールバックされ、Databricks は副作用なしでトランザクションを終了します。

トランザクションの実践的な練習については、「 チュートリアル: テーブル間でトランザクションを調整する」を参照してください。

必要条件

複数のステートメントまたは複数のテーブルにまたがるトランザクションを実行するには:

  • 書き込まれるすべてのテーブルは、次の条件を満たす必要があります。
  • サポートされているコンピューティングを使用します。
    • 非対話型トランザクションの場合は、Databricks Runtime 18.0 以降を実行している SQL ウェアハウス、サーバーレス コンピューティング、またはクラスターを使用します。
    • 対話型トランザクションの場合は、任意の SQL ウェアハウスを使用します。
    • OpenSharing 共有資産のトランザクションの場合は、Databricks Runtime 18.1 以降を使用します。

トランザクション モード

Azure Databricksでは、次の 2 つのトランザクション モードがサポートされています。

モード 構文 コミット ロールバック 最適な用途
非対話型 ATOMIC 複合ステートメント 成功時の自動 エラー時の自動 固定シーケンス、スケジュールされたジョブ
インタラクティブ BEGIN TRANSACTION; COMMIT; 手動 手動 条件付きロジック, 検証とデバッグ, JDBC, ODBC, PyODBC

両方のモードの構文、例、使用パターンの詳細については、「 トランザクション モード」を参照してください。

サポートされている操作

トランザクション内で次の操作を使用できます。

Operation 説明
SELECT (サブセレクト) データのクエリと結果の検証
VALUES 条項 テスト データまたは定数値を生成する
INSERT (すべてのバリアントを含む) 新しい行を追加する
UPDATE 既存の行を変更する
COPY INTO ファイルから Delta テーブルにデータを読み込む
DELETE FROM 行を削除する
MERGE INTO 挿入、更新、削除を組み合わせたアップサート パターン

サポートされている読み取りソースと書き込みシンク

トランザクションを使用すると、Unity カタログ テーブル (Delta Lake と Iceberg)、ストリーミング テーブル、ビュー、具体化されたビューから読み取ります。

ACID の保証により、Delta Lake や Iceberg などのオープン テーブル形式は、読み取りソースと書き込みシンクの両方としてトランザクションでサポートされます。 非トランザクション ソースから読み取る場合は、 allow_nontransactional_read ヒントを使用します。 非トランザクション ソースからの読み取りと例: 非トランザクション読み取りを参照してください。

非トランザクション ソースからの読み取り

Warnung

非トランザクション読み取りは繰り返し可能ではありません。 トランザクション中にソース データを同時に変更すると、読み取りの整合性が失われる可能性があります。

トランザクションを使用すると、非トランザクション ソースから読み取りを行えます。 非トランザクション ソースには、Parquet、Avro、CSV、JSON ファイル形式を使用した外部テーブル、 および JDBC を使用したフェデレーション テーブルが含まれます。 非トランザクション ソースを読み取る場合は、名前でソースを参照し、 allow_nontransactional_read ヒントを使用します。

パスベースのアクセスはサポートされていません。 FROM parquet.`/path/to/data`などのパスでファイルを直接参照すると、トランザクションはPATH_BASED_ACCESS エラーで失敗します。

次のコード例は、JSON を使用して外部テーブルでヒントを使用する方法を示しています。

BEGIN TRANSACTION;
-- Non-transactional source, hint required
INSERT INTO transactional_table
SELECT col1, col2
FROM external_json_table
WITH (allow_nontransactional_read = true);

COMMIT;

例: 非トランザクション読み込み

次の例は、Parquet を使用した外部テーブルからの非トランザクション読み取りを示しています。 この例では、読み取りおよび書き込みアクセス権を持つ既存の外部の場所が必要です。

Azure Data Lake Storage Gen2 (ADLS Gen2) 外部の場所への接続を参照してください。

Parquet ソースを名前付き外部テーブルとして登録するには、次のコマンドを実行します。

CREATE TABLE main.default.external_parquet_table
USING PARQUET
LOCATION 'abfss://my-container@my-storage-account.dfs.core.windows.net/path/to/data'; -- existing external location

トランザクションで Delta Lake を使用して非トランザクション Parquet ソースとマネージド テーブルの両方を読み取るために、次のコマンドを実行します。

BEGIN ATOMIC
-- Non-transactional source, hint required
INSERT INTO transactional_table
SELECT col1, col2
FROM external_parquet_table
WITH (allow_nontransactional_read = true);

-- Managed table source, no hint is required
INSERT INTO another_table
SELECT * FROM managed_delta_table;
END;

トランザクションの分離

トランザクションでは、すべてのステートメントで反復可能な読み取りが可能です。 トランザクション内のテーブルにアクセスすると、Azure Databricksは最初のアクセス時にそのテーブルの一貫性のあるスナップショットをキャプチャします。 そのテーブルの後続の読み取りはすべてこのスナップショットを使用するため、他のユーザーが同じテーブルを同時に変更した場合でも読み取りの一貫性が維持されます。

次の例では、トランザクションで products する最初のクエリによって、一貫性のあるスナップショットがキャプチャされます。

非対話型

BEGIN ATOMIC
  SELECT * FROM products WHERE product_id = 1001;
  SELECT * FROM products WHERE product_id = 1001;
END;

インタラクティブ

BEGIN TRANSACTION;
SELECT * FROM products WHERE product_id = 1001;
SELECT * FROM products WHERE product_id = 1001;
COMMIT;

次に、別のユーザーが 2 番目のクエリを開始する前に、 product_id = 1001 の行を同時に更新するとします。

UPDATE products SET price = 29.99 WHERE product_id = 1001;

スナップショットは最初のアクセス時にキャプチャされたため、 products する 2 番目のクエリは、更新された行ではなく、元の行を返します。

競合の検出とコンカレンシー

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 では、ほとんどのユース ケースで非対話型トランザクションが推奨されます。非対話型トランザクションでは行レベルのコンカレンシーが使用されます。 非対話型トランザクションを参照してください。
  • 競合時の再試行: 競合が発生した場合は、新しいデータを使用してトランザクションを再試行します。

異なるクライアントからのトランザクションを使用する

トランザクションは、さまざまなクライアント インターフェイスで機能します。

制限事項

トランザクションには、次の制限事項が適用されます。

制限事項 説明
対話型トランザクションの競合 対話型トランザクション (BEGIN TRANSACTION; ... COMMIT;)は非対話型トランザクションよりも保守的な競合検出を使用し、ターゲット テーブルから読み取らない INSERT 操作を除き、テーブル レベルで競合する可能性があります。 行レベルの競合検出が重要な場合は、非対話型トランザクション (ATOMIC 複合ステートメント) を使用します。 非対話型トランザクションを参照してください。
ターゲットを書き込む catalogManaged テーブル機能が有効になっている Unity カタログマネージド Delta テーブルまたは Iceberg テーブルにのみ書き込むことができます。 カタログのコミットを参照してください。
DML 操作のみ トランザクションでは、 SELECTINSERTUPDATEDELETECOPY INTO、および MERGEがサポートされます。 トランザクションの外部で、 CREATE TABLEALTER TABLEDROP TABLEなどの DDL 操作を実行します。
メタデータ操作はサポートされていません メタデータ操作は、プロトコルに関係なく、トランザクション内では機能しません。 これには、Thrift RPC ベースのメタデータ呼び出し (JDBC DatabaseMetaData メソッドや ODBC カタログ関数など)、SQL ベースのコマンド (SHOW TABLESSHOW DATABASESDESCRIBE TABLE)、SELECT テーブルまたはシステム テーブルに対するinformation_schemaクエリが含まれます。 トランザクションの外部でメタデータ操作を実行します。
COPY INTO 並行 処理 COPY INTO コマンドを実行しているトランザクションは、別のCOPY INTO コマンドが同時に実行され、同じテーブルに書き込み、先にコミットされると失敗します。
ストリーミング書き込みがサポートされていません ストリーミング テーブルへのトランザクション書き込みはサポートされていません。
RLS テーブルと CLM テーブルはサポートされていません 行フィルターと列マスクを含むテーブルは、トランザクションに参加できません。
テーブルとビューの制限 トランザクションは、最大 100 個のテーブルとの間で読み取りまたは書き込みを行い、最大 100 個のビューから読み取ることができます。 各テーブルは、トランザクション内で最大 100 個の中間コミットを持つことができます。
タイム トラベルはサポートされていません トランザクション内で タイム トラベル を使用することはできません。
無操作タイムアウト 対話型トランザクションは、非アクティブ状態が 10 分続くとロールバックされます。 トランザクションは副作用なしで終了しますが、セッションがまだアクティブな場合は、 ROLLBACK を明示的 に実行してトランザクションの状態をクリアする必要があります。
系列 トランザクションは、読み取りと書き込みが行われるたびに 系列 を生成します。 系列イベントは、トランザクションがロールバックされた場合でも保持されます。
最大期間 すべてのトランザクションは、合計期間が 48 時間後に自動的にロールバックされます。 対話型トランザクションの場合、トランザクションは副作用なしで終了しますが、セッションがまだアクティブな場合は、ROLLBACK を明示的 に実行して トランザクションの状態をクリアする必要があります。
OpenSharing 共有テーブルの要件 OpenSharing プロバイダーは、受信者がトランザクションを実行できるように、テーブル WITH HISTORYを共有する必要があります。 受信者は、任意の種類のコンピューティングを使用してトランザクションを実行できます。
OpenSharing 受信者のコンピューティング制限 Azure Databricks受信者は、共有ビュー、具体化されたビュー、ストリーミング テーブル、Iceberg 以外の外部テーブルでのみトランザクションを実行できます。 プロバイダーと同じAzure Databricks アカウント内の受信者は、共有コンピューティングまたはサーバーレス コンピューティングを使用する必要があります。 別のアカウントの受信者は、サーバーレス コンピューティングを使用する必要があります。
OpenSharing ソース テーブルの競合 OpenSharing 受信者は、1 つのトランザクション内で同じソース テーブルを参照する共有ビューと共有テーブルを参照できません。

その他のリソース