Share via


Transactiemodi

Belangrijk

Transacties die naar beheerde Delta-tabellen van Unity Catalog schrijven, bevinden zich in openbare preview.

Transacties die naar beheerde Iceberg-tabellen in Unity Catalog schrijven, bevinden zich in private preview. Als u wilt deelnemen aan deze preview, dient u het voorbeeldformulier voor beheerde Iceberg-tabellen in.

Transacties ondersteunen twee modi: niet-interactief en interactief. Deze pagina bevat informatie over het gebruik van elke modus en bevat implementatievoorbeelden.

Zie Transacties voor vereisten en een overzicht van transacties. Zie Zelfstudie: Transacties coördineren tussen tabellen voor praktische praktijk met beide modi.

Opmerking

Alle tabellen waarnaar in transacties met meerdere statements en meerdere tabellen is geschreven, moeten:

Niet-interactieve transacties

Niet-interactieve transacties maken gebruik van SQL-scripts met het ATOMIC trefwoord. Het atomische samengestelde instructieblok voert alle instructies uit als één atomische eenheid. Ze slagen allemaal samen of mislukken allemaal.

Ondersteunde berekeningen: elk SQL-warehouse, serverloze rekenkracht of cluster waarop Databricks Runtime 18.0 en hoger wordt uitgevoerd.

Ondersteunde syntaxis: ondersteunt SQL-, Scala-blokken spark.sql en PySpark-blokken spark.sql .

Opmerking

U kunt niet-interactieve transacties binnen Structured Streaming's forEachBatch gebruiken door aan te roepen spark.sql("BEGIN ATOMIC ... END;"). Structured Streaming-controlepunten gaan echter niet transactievormig verder.

Syntaxis

BEGIN ATOMIC
  statement1;
  statement2;
  statement3;
END;

In Azure Databricks worden automatisch alle wijzigingen doorgevoerd als alle instructies slagen. Als er een instructie mislukt, worden alle wijzigingen automatisch teruggedraaid in Azure Databricks.

Gebruiken in SQL-editor

Voer niet-interactieve transacties rechtstreeks uit in de SQL-editor. Selecteer het volledige atomische samengestelde instructieblok en voer het uit als één instructie:

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;

Gebruik in notebooks

Voer niet-interactieve transacties uit in notebooks met behulp van SQL-cellen of programmatische API's.

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;
""")

Gebruik in geplande taken

Niet-interactieve transacties werken goed in geplande opdrachten omdat ze automatisch commit (doorvoeren) en rollback (terugdraaien) verwerken.

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;

Als een opdracht mislukt, inclusief de assertie, wordt de gehele transactie automatisch teruggedraaid.

Gebruiken met JDBC

Externe clients kunnen niet-interactieve transacties uitvoeren.

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);

Gebruiken met api voor het uitvoeren van instructies

Niet-interactieve transacties uitvoeren met behulp van de API voor het uitvoeren van instructies:

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-patronen

In de volgende patronen ziet u algemene ETL-werkstromen met behulp van niet-interactieve transacties.

Faserings- en validatiepatroon

Dit patroon laadt gegevens in een faseringsgebied, valideert de gegevenskwaliteit en voegt gevalideerde records samen in productietabellen:

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;

Dimensie- en feitentabelpatroon

Met dit patroon worden dimensietabellen bijgewerkt voordat feitentabellen worden geladen om referentiële integriteit te behouden:

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;

Foutafhandeling

Wanneer een instructie binnen een BEGIN ATOMIC ... END; blok mislukt, worden alle wijzigingen door Azure Databricks teruggedraaid en wordt er een foutbericht geretourneerd.

Tips voor foutopsporing:

  1. Bekijk het foutbericht om te bepalen welke instructie is mislukt.
  2. Test verklaringen afzonderlijk buiten het transactieblok.
  3. Voeg validatiecontroles toe met behulp van SIGNAL om te mislukken met aangepaste foutberichten.
  4. Opvraag transactiegeschiedenis voor extra context.

Interactieve transacties

Interactieve transacties geven u expliciet controle over transactiegrenzen. U kunt handmatig een transactie starten, instructies uitvoeren en expliciet doorvoeren of terugdraaien.

Ondersteunde berekeningen: alleen SQL-warehouses .

Ondersteunde syntaxis: alleen SQL.

Syntaxis

BEGIN TRANSACTION;

statement1;
statement2;

COMMIT;
-- or: ROLLBACK;

Valideren voordat u doorvoert

Gebruik interactieve transacties om resultaten te valideren voordat u het doorvoert:

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;

Expliciete terugdraaiing

Een transactie terugdraaien wanneer validatie mislukt of bedrijfslogica vereist dat wijzigingen worden genegeerd:

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;

Gebruiken met JDBC

Het JDBC-stuurprogramma ondersteunt het uitvoeren van DML-instructies door gebruik van executeUpdate() binnen transacties. Zie Ondersteunde bewerkingen voor een lijst met ondersteunde DML-instructies.

JDBC-clients gebruiken interactieve transacties door de modus voor automatisch doorvoeren uit te schakelen:

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();
}

Niet-ondersteunde JDBC-bewerkingen

De volgende JDBC-bewerkingen worden niet ondersteund binnen interactieve transacties:

Categorie Niet ondersteund
Schakelen tussen catalogi of schema's Connection.setCatalog() en Connection.setSchema()
Wijzigingen in sessieconfiguratie Connection.setClientInfo() voor eigenschappen op sessieniveau, zoals TIMEZONE en ANSI_MODE
Alle DatabaseMetaData (alle protocollen) Alle DatabaseMetaData.* methoden
Metagegevens van PreparedStatement PreparedStatement.getMetaData()
opgeslagen procedures CALL procedure_name()

Gebruiken met ODBC

Het ODBC-stuurprogramma ondersteunt het uitvoeren van DML-instructies met behulp van SQLExecute() en SQLExecDirect() binnen transacties. Zie Ondersteunde bewerkingen voor een lijst met ondersteunde DML-instructies.

ODBC-clients kunnen interactieve transacties gebruiken met het ODBC-stuurprogramma van Azure Databricks met behulp van standaard-ODBC-transactiebeheerfuncties.

Niet-ondersteunde ODBC-bewerkingen

De volgende ODBC-bewerkingen worden niet ondersteund binnen interactieve transacties:

Categorie Niet ondersteund
Alle functies van de catalogus SQLTables, SQLColumns, SQLStatistics, SQLSpecialColumns, SQLPrimaryKeys, SQLForeignKeys, SQLTablePrivileges, SQLColumnPrivileges, SQLProcedures, SQLProcedureColumns
Verbindingskenmerken instellen Wijzigingen in het schakelen tussen catalogi, wijzigingen van het isolatieniveau en wijzigingen van de toegangsmodus met SQLSetConnectAttr()
SQL-vertaling SQLNativeSql

Gebruiken met de Databricks SQL Connector voor Python

De Databricks SQL Connector voor Python ondersteunt het uitvoeren van DML-instructies met behulp van cursor.execute() binnen transacties. Zie Ondersteunde bewerkingen voor een lijst met ondersteunde DML-instructies.

Python-toepassingen kunnen interactieve transacties gebruiken met de Databricks SQL Connector voor Python door het volgende in te stellen 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()

Niet-ondersteunde Python-connectorbewerkingen

De volgende Python-connectorbewerkingen worden niet ondersteund binnen interactieve transacties:

Categorie Niet ondersteund
Alle metagegevens cursor.catalogs(),cursor.schemas(),cursor.tables(),cursor.columns()

Beperkingen van stuurprogramma's voor interactieve transacties

De volgende beperkingen gelden voor alle stuurprogramma's bij het gebruik van interactieve transacties.

Metagegevensbewerkingen worden niet ondersteund in interactieve transacties. De volgende bewerkingen kunnen mislukken binnen een transactie, ongeacht het stuurprogramma of protocol:

Stuurprogramma/protocol Typ Methods
JDBC DatabaseMetaData getCatalogs() getSchemas(), getTables(), getColumns()getTypeInfo()
ODBC Catalogusfuncties SQLTables, SQLColumns, SQLGetTypeInfo
Python connector Metagegevensmethoden cursor.catalogs(),cursor.schemas(),cursor.tables(),cursor.columns()
SQL Metagegevensopdrachten SHOW TABLES SHOW DATABASES, DESCRIBE TABLE, USE CATALOGUSE SCHEMA
SQL information_schema SELECT queries op information_schema tabellen

Voer alle metagegevensbewerkingen buiten transacties uit.

Waarschuwing

Het uitvoeren van transacties op meerdere threads op één verbindingsobject van één stuurprogramma leidt tot niet-gedefinieerd gedrag. Voer slechts één transactie tegelijk uit op elk verbindingsobject.

Isolatiegedrag

Niet-doorgevoerde wijzigingen in een interactieve transactie zijn alleen zichtbaar voor uw sessie. Andere sessies zien de tabelstatus zoals het was voordat uw transactie begon.

Opmerking

Interactieve transacties maken gebruik van conservatievere conflictdetectie dan niet-interactieve transacties en kunnen conflicteren op tabelniveau (met uitzondering van onvoorwaardelijke toevoegbewerkingen). Gebruik voor conflictdetectie op rijniveau transacties zonder interactie (BEGIN ATOMIC ... END;).

  1. Als u isolatie wilt controleren, maakt u de voorbeeldtabel als deze niet bestaat:
CREATE TABLE IF NOT EXISTS sample_accounts (
  id INT,
  account_name STRING,
  balance DECIMAL(10,2)
) USING DELTA
TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported');
  1. Start in dezelfde sessie een transactie en breng een wijziging aan:

    BEGIN TRANSACTION;
    INSERT INTO sample_accounts VALUES (10, 'Test', 100.00);
    
  2. Voer in een afzonderlijke SQL Editor-tabblad of notebooksessie (geen nieuwe cel in hetzelfde notebook) een query uit op de tabel:

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

    Dit retourneert 0 rijen omdat de niet-doorgevoerde wijziging niet zichtbaar is buiten uw eerste sessie.

  3. Ga terug naar uw eerste sessie en voer deze door:

    COMMIT;
    
  4. Voer opnieuw een query uit de tweede sessie uit:

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

    De rij is zichtbaar omdat de transactie is doorgevoerd.

Deze isolatie voorkomt dat andere gebruikers gegevens lezen die mogelijk worden teruggedraaid.

Een transactiemodus kiezen

Scenario Aanbevolen modus
Geplande ETL-taken Niet-interactief: automatisch doorvoeren of terugdraaien vereenvoudigt foutafhandeling
Vaste verklaringsreeksen Niet-interactief: eenvoudigere syntaxis, geen handmatige doorvoer nodig
Gegevensvalidatie vóór doorvoer Interactief: resultaten controleren en bepalen of ze moeten worden doorgevoerd
JDBC-toepassingen die handmatig beheer nodig hebben Interactief: standaarddatabasetransactiepatronen

Volgende stappen