Freigeben über


Transaktionsmodi

Von Bedeutung

Transaktionen, die in verwaltete Delta-Tabellen im Unity-Katalog schreiben, befinden sich in der öffentlichen Vorschau.

Transaktionen, die in verwaltete Iceberg-Tabellen im Unity-Katalog schreiben, befinden sich in der privaten Vorschau. Um dieser Vorschau beizutreten, übermitteln Sie das Vorschauformular für verwaltete Iceberg-Tabellen.

Transaktionen unterstützen zwei Modi: nicht interaktiv und interaktiv. Auf dieser Seite wird erläutert, wann jeder Modus verwendet werden soll und Implementierungsbeispiele enthalten sind.

Informationen zu Anforderungen und einer Übersicht über Transaktionen finden Sie unter "Transaktionen". Praktische Übungen mit beiden Modi finden Sie im Lernprogramm: Koordinieren von Transaktionen über Tabellen hinweg.

Hinweis

Alle Tabellen, die in einer Mehranweisungs- und Mehrtabellentransaktion beschrieben werden, müssen Folgendes erfüllen:

Nicht interaktive Transaktionen

Nicht interaktive Transaktionen verwenden SQL-Skripting mit dem ATOMIC Schlüsselwort. Der ATOMIC-Verbundanweisungsblock führt alle Anweisungen als eine einzelne atomare Einheit aus. Alle sind zusammen erfolgreich oder alle schlagen zusammen fehl.

Unterstützte Berechnung: Jedes SQL Warehouse, serverloses Computing oder Cluster, das Databricks Runtime 18.0 oder höher ausführt.

Unterstützte Syntax: Unterstützt SQL-, Skala-Blöcke spark.sql und PySpark-Blöcke spark.sql .

Hinweis

Sie können nicht-interaktive Transaktionen innerhalb von Structured Streaming forEachBatch verwenden, indem Sie spark.sql("BEGIN ATOMIC ... END;") aufrufen. Strukturierte Streaming-Prüfpunkte werden jedoch nicht tranzaktional voranschreiten.

Syntax

BEGIN ATOMIC
  statement1;
  statement2;
  statement3;
END;

Azure Databricks übernimmt automatisch alle Änderungen, wenn alle Anweisungen erfolgreich sind. Wenn eine Anweisung fehlschlägt, setzt Azure Databricks automatisch alle Änderungen zurück.

Verwenden im SQL-Editor

Führen Sie nicht interaktive Transaktionen direkt im SQL-Editor aus. Wählen Sie den gesamten ATOM-Verbund-Anweisungsblock aus, und führen Sie ihn als einzelne Anweisung aus:

BEGIN ATOMIC
  DELETE FROM staging_sales WHERE load_date < current_date() - INTERVAL 7 DAYS;

  INSERT INTO staging_sales
  SELECT * FROM raw_sales WHERE load_date = current_date();

  MERGE INTO sales AS target
  USING staging_sales AS source
  ON target.sale_id = source.sale_id
  WHEN MATCHED THEN UPDATE SET *
  WHEN NOT MATCHED THEN INSERT *;
END;

Verwenden in Notizbüchern

Führen Sie nicht interaktive Transaktionen in Notizbüchern mithilfe von SQL-Zellen oder programmgesteuerten APIs aus.

SQL

BEGIN ATOMIC
  UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 2001;
  UPDATE inventory SET quantity = quantity + 10 WHERE product_id = 2002;
  INSERT INTO inventory_moves (from_product, to_product, quantity, move_date)
  VALUES (2001, 2002, 10, current_date());
END;

Python

spark.sql("""
BEGIN ATOMIC
  UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 2001;
  UPDATE inventory SET quantity = quantity + 10 WHERE product_id = 2002;
  INSERT INTO inventory_moves (from_product, to_product, quantity, move_date)
  VALUES (2001, 2002, 10, current_date());
END;
""")

Scala

spark.sql("""
BEGIN ATOMIC
  UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 2001;
  UPDATE inventory SET quantity = quantity + 10 WHERE product_id = 2002;
  INSERT INTO inventory_moves (from_product, to_product, quantity, move_date)
  VALUES (2001, 2002, 10, current_date());
END;
""")

Verwendung in geplanten Aufträgen

Nicht interaktive Transaktionen funktionieren gut in geplanten Aufträgen, da sie Commit und Rollback automatisch behandeln:

BEGIN ATOMIC
  -- Clear previous staging data
  DELETE FROM staging_daily_sales WHERE load_date = current_date();

  -- Load new data
  INSERT INTO staging_daily_sales
  SELECT sale_id, customer_id, amount, sale_date, current_date() as load_date
  FROM raw_sales
  WHERE sale_date = current_date() - INTERVAL 1 DAY;

  -- Validate row count (fails transaction if no data)
  IF (SELECT COUNT(*) FROM staging_daily_sales WHERE load_date = current_date()) = 0 THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No sales data loaded for yesterday';
  END IF;

  -- Merge into production
  MERGE INTO daily_sales AS target
  USING staging_daily_sales AS source
  ON target.sale_id = source.sale_id
  WHEN MATCHED THEN UPDATE SET *
  WHEN NOT MATCHED THEN INSERT *;
END;

Wenn eine Anweisung fehlschlägt, einschließlich der Assertion, wird die gesamte Transaktion automatisch zurückgesetzt.

Verwendung mit ODBC

Externe Clients können nicht interaktive Transaktionen ausführen.

JDBC

String sql = """
    BEGIN ATOMIC
      INSERT INTO orders (order_id, total) VALUES (1001, 500.00);
      UPDATE customers SET last_order = CURRENT_DATE() WHERE customer_id = 5001;
    END;
    """;

Statement stmt = conn.createStatement();
stmt.execute(sql);

Verwendung mit Anweisungsausführungs-API

Ausführen nicht interaktiver Transaktionen mithilfe der Anweisungsausführungs-API:

import requests

sql = """
BEGIN ATOMIC
  INSERT INTO sales (sale_id, amount) VALUES (3001, 750.00);
  UPDATE daily_totals SET total = total + 750.00 WHERE sale_date = CURRENT_DATE();
END;
"""

response = requests.post(
    f"{workspace_url}/api/2.0/sql/statements",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "warehouse_id": warehouse_id,
        "statement": sql,
        "wait_timeout": "30s"
    }
)

ETL-Muster

Die folgenden Muster veranschaulichen allgemeine ETL-Workflows mit nicht interaktiven Transaktionen.

Staging- und Validierungsmuster

Dieses Muster lädt Daten in einen Stagingbereich, überprüft die Datenqualität und führt validierte Datensätze in Produktionstabellen zusammen:

BEGIN ATOMIC
  -- Load into staging
  INSERT INTO staging_customers
  SELECT * FROM external_source
  WHERE ingest_date = current_date();

  -- Validate data quality
  IF (SELECT COUNT(*) FROM staging_customers WHERE email NOT LIKE '%@%') > 0 THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid email addresses found';
  END IF;

  -- Merge validated data
  MERGE INTO customers AS target
  USING staging_customers AS source
  ON target.customer_id = source.customer_id
  WHEN MATCHED THEN UPDATE SET *
  WHEN NOT MATCHED THEN INSERT *;

  -- Update metadata
  UPDATE etl_metadata
  SET last_load_date = current_date(),
      rows_processed = (SELECT COUNT(*) FROM staging_customers)
  WHERE table_name = 'customers';
END;

Muster für Dimension und Faktentabelle

Dieses Muster aktualisiert Dimensionstabellen, bevor Faktentabellen geladen werden, um die referenzielle Integrität beizubehalten:

BEGIN ATOMIC
  -- Update dimension tables first
  MERGE INTO dim_products AS target
  USING staging_products AS source
  ON target.product_id = source.product_id
  WHEN MATCHED THEN UPDATE SET *
  WHEN NOT MATCHED THEN INSERT *;

  MERGE INTO dim_customers AS target
  USING staging_customers AS source
  ON target.customer_id = source.customer_id
  WHEN MATCHED THEN UPDATE SET *
  WHEN NOT MATCHED THEN INSERT *;

  -- Then load fact table with foreign key references
  INSERT INTO fact_sales
  SELECT s.sale_id, p.product_key, c.customer_key, s.sale_amount, s.sale_date
  FROM staging_sales s
  JOIN dim_products p ON s.product_id = p.product_id
  JOIN dim_customers c ON s.customer_id = c.customer_id;
END;

Fehlerbehandlung

Wenn eine Anweisung innerhalb eines BEGIN ATOMIC ... END; Blocks fehlschlägt, setzt Azure Databricks alle Änderungen zurück und gibt eine Fehlermeldung zurück.

Tipps zum Debuggen:

  1. Überprüfen Sie die Fehlermeldung, um zu ermitteln, welche Anweisung fehlgeschlagen ist.
  2. Testanweisungen einzeln außerhalb des Transaktionsblocks.
  3. Fügen Sie Überprüfungen mithilfe von SIGNAL hinzu, um bei Fehlern benutzerdefinierte Fehlermeldungen auszugeben.
  4. Überprüfen Sie den Transaktionsverlauf für zusätzlichen Kontext.

Interaktive Transaktionen

Interaktive Transaktionen ermöglichen Ihnen die explizite Kontrolle über Transaktionsgrenzen. Sie beginnen manuell eine Transaktion, führen Anweisungen aus und machen explizit ein Commit oder ein Rollback.

Unterstützte Berechnung: nur SQL-Warehouses.

Unterstützte Syntax: Nur SQL.

Syntax

BEGIN TRANSACTION;

statement1;
statement2;

COMMIT;
-- or: ROLLBACK;

Überprüfen vor dem Commit

Verwenden Sie interaktive Transaktionen, um Ergebnisse zu überprüfen, bevor Sie commiten:

BEGIN TRANSACTION;

-- Load staging data
INSERT INTO staging_customers
SELECT * FROM external_customers
WHERE load_date = current_date();

-- Validate and commit or rollback
BEGIN
  DECLARE duplicate_count INT;
  SET duplicate_count = (
    SELECT COUNT(*) FROM (
      SELECT customer_id, COUNT(*) as cnt
      FROM staging_customers
      WHERE load_date = current_date()
      GROUP BY customer_id
      HAVING COUNT(*) > 1
    )
  );

  IF duplicate_count > 0 THEN
    ROLLBACK;
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Duplicate customers found in staging data';
  ELSE
    MERGE INTO customers AS target
    USING staging_customers AS source
    ON target.customer_id = source.customer_id
    WHEN MATCHED THEN UPDATE SET *
    WHEN NOT MATCHED THEN INSERT *;
    COMMIT;
  END IF;
END;

Explizites Rollback

Führen Sie ein Rollback einer Transaktion durch, wenn die Überprüfung fehlschlägt oder die Geschäftslogik das Verwerfen von Änderungen erfordert.

BEGIN TRANSACTION;

UPDATE inventory
SET quantity = quantity - 50
WHERE product_id = 2001;

-- Check if quantity would go negative
BEGIN
  DECLARE new_quantity INT;
  SET new_quantity = (SELECT quantity FROM inventory WHERE product_id = 2001);

  IF new_quantity < 0 THEN
    ROLLBACK;
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insufficient inventory for product 2001';
  ELSE
    COMMIT;
  END IF;
END;

Verwendung mit ODBC

Der JDBC-Treiber unterstützt das Ausführen von DML-Anweisungen mithilfe von executeUpdate() innerhalb von Transaktionen. Eine Liste der unterstützten DML-Anweisungen finden Sie unter "Unterstützte Vorgänge".

JDBC-Clients verwenden interaktive Transaktionen, indem sie den Auto-Commit-Modus deaktivieren.

Connection conn = DriverManager.getConnection(jdbcUrl, properties);

try {
    conn.setAutoCommit(false);  // Start transaction mode
    Statement stmt = conn.createStatement();

    stmt.executeUpdate("INSERT INTO accounts (account_id, balance) VALUES (1001, 5000)");
    stmt.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE account_id = 1001");

    conn.commit();  // Commit the transaction

} catch (SQLException e) {
    conn.rollback();  // Roll back on error
    throw e;
} finally {
    conn.close();
}

Nicht unterstützte JDBC-Operationen

Die folgenden JDBC-Operationen werden in interaktiven Transaktionen nicht unterstützt:

Kategorie Nicht unterstützt
Katalog- oder Schemawechsel Connection.setCatalog() und Connection.setSchema()
Sitzungskonfigurationsänderungen Connection.setClientInfo() für Eigenschaften auf Sitzungsebene, wie TIMEZONE und ANSI_MODE
Alle DatabaseMetaData (alle Protokolle) Alle DatabaseMetaData.* Methoden
PreparedStatement Metadaten PreparedStatement.getMetaData()
Gespeicherte Prozeduren CALL procedure_name()

Verwenden mit ODBC

Der ODBC-Treiber unterstützt die Ausführung von DML-Anweisungen mithilfe SQLExecute() und SQLExecDirect() innerhalb von Transaktionen. Eine Liste der unterstützten DML-Anweisungen finden Sie unter "Unterstützte Vorgänge".

ODBC-Clients können interaktive Transaktionen mit dem ODBC-Treiber von Azure Databricks mit standardmäßigen ODBC-Transaktionsverwaltungsfunktionen verwenden.

Nicht unterstützte ODBC-Vorgänge

Die folgenden ODBC-Vorgänge werden in interaktiven Transaktionen nicht unterstützt:

Kategorie Nicht unterstützt
Alle Katalogfunktionen SQLTables, SQLColumns, SQLStatistics, SQLSpecialColumns, SQLPrimaryKeys, SQLForeignKeys, SQLTablePrivileges, SQLColumnPrivileges, SQLProcedures, SQLProcedureColumns
Festlegen von Verbindungsattributen Katalogwechsel, Änderungen der Isolationsebene und des Zugriffsmodus mithilfe von SQLSetConnectAttr()
SQL-Übersetzung SQLNativeSql

Verwenden mit dem Databricks SQL Connector für Python

Der Databricks SQL Connector für Python unterstützt das Ausführen von DML-Anweisungen in cursor.execute() Transaktionen. Eine Liste der unterstützten DML-Anweisungen finden Sie unter "Unterstützte Vorgänge".

Python-Anwendungen können interaktive Transaktionen mit dem Databricks SQL Connector für Python verwenden, indem Sie Folgendes festlegen autocommit=False:

from databricks import sql

with sql.connect(
    server_hostname="dbc-a1b2345c-d6e7.cloud.databricks.com",
    http_path="sql/1.0/warehouses/abc123def456",
    access_token="your-access-token",
    autocommit=False
) as connection:
    with connection.cursor() as cursor:
        cursor.execute("INSERT INTO accounts (account_id, balance) VALUES (1001, 5000)")
        cursor.execute("UPDATE accounts SET balance = balance - 100 WHERE account_id = 1001")
        connection.commit()

Nicht unterstützte Python-Connectorvorgänge

Die folgenden Python-Connectorvorgänge werden in interaktiven Transaktionen nicht unterstützt:

Kategorie Nicht unterstützt
Alle Metadaten cursor.catalogs() cursor.schemas() cursor.tables() cursor.columns()

Treiberbeschränkungen für interaktive Transaktionen

Die folgenden Einschränkungen gelten für alle Treiber bei der Verwendung interaktiver Transaktionen.

Metadatenvorgänge werden in interaktiven Transaktionen nicht unterstützt. Die folgenden Vorgänge können unabhängig vom Treiber oder Protokoll innerhalb einer Transaktion fehlschlagen:

Treiber/Protokoll Typ Methodik
JDBC DatabaseMetaData getCatalogs(), , getSchemas()getTables(), , getColumns()getTypeInfo()
ODBC Katalogfunktionen SQLTables, SQLColumnsSQLGetTypeInfo
Python Connector Metadatenmethoden cursor.catalogs() cursor.schemas() cursor.tables() cursor.columns()
SQL Metadatenbefehle SHOW TABLES, , SHOW DATABASESDESCRIBE TABLE, , USE CATALOGUSE SCHEMA
SQL information_schema SELECT Abfragen gegen information_schema Tabellen

Führen Sie alle Metadatenvorgänge außerhalb von Transaktionen aus.

Warnung

Das Ausführen von Transaktionen auf mehreren Threads eines einzelnen Treiberverbindungsobjekts führt zu einem nicht definierten Verhalten. Führen Sie jeweils nur eine Transaktion für jedes Verbindungsobjekt aus.

Isolationsverhalten

Nicht freigegebene Änderungen in einer interaktiven Transaktion sind nur für Ihre Sitzung sichtbar. In anderen Sitzungen wird der Tabellenstatus wie vor Beginn der Transaktion angezeigt.

Hinweis

Interaktive Transaktionen verwenden eine konservativere Konflikterkennung als nicht-interaktive Transaktionen und können auf Tabellenebene (mit Ausnahme von unbedingten Anfügungen) Konflikte verursachen. Verwenden Sie für die Konflikterkennung auf Zeilenebene nicht interaktive Transaktionen (BEGIN ATOMIC ... END;).

  1. Um die Isolation zu überprüfen, erstellen Sie die Beispieltabelle, falls sie nicht vorhanden ist:
CREATE TABLE IF NOT EXISTS sample_accounts (
  id INT,
  account_name STRING,
  balance DECIMAL(10,2)
) USING DELTA
TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported');
  1. Starten Sie in derselben Sitzung eine Transaktion, und nehmen Sie eine Änderung vor:

    BEGIN TRANSACTION;
    INSERT INTO sample_accounts VALUES (10, 'Test', 100.00);
    
  2. Fragen Sie in einer separaten SQL Editor-Registerkarte oder Notizbuchsitzung (keine neue Zelle im selben Notizbuch) die Tabelle ab:

    -- Run this in the SECOND session
    SELECT * FROM sample_accounts WHERE id = 10;
    

    Dies gibt 0 Zeilen zurück, da die nicht abgeschlossene Änderung außerhalb der ersten Sitzung nicht sichtbar ist.

  3. Kehren Sie zu Ihrer ersten Sitzung zurück, und führen Sie einen Commit durch:

    COMMIT;
    
  4. Abfrage aus der zweiten Sitzung erneut:

    -- Run this in the SECOND session
    SELECT * FROM sample_accounts WHERE id = 10;
    

    Die Zeile ist sichtbar, da die Transaktion bestätigt wurde.

Diese Isolation verhindert, dass andere Benutzer Daten lesen, die möglicherweise rückgängig gemacht werden.

Auswählen eines Transaktionsmodus

Szenario Empfohlener Modus
Geplante ETL-Aufträge Nicht interaktiv – automatisches Commit oder Rollback vereinfacht die Fehlerbehandlung
Feste Anweisungfolgen Nicht interaktiv – einfachere Syntax, kein manueller Commit erforderlich
Datenüberprüfung vor Commit Interaktiv – Überprüfen der Ergebnisse und Entscheiden, ob ein Commit ausgeführt werden soll
JDBC-Anwendungen, die manuelle Steuerung benötigen Interaktiv – Standarddatenbanktransaktionsmuster

Nächste Schritte