Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Importante
Le transazioni che scrivono nelle tabelle Delta gestite del catalogo Unity sono in anteprima pubblica.
Le transazioni che scrivono nelle tabelle Iceberg gestite dal catalogo Unity sono in anteprima privata. Per partecipare a questa anteprima, inviare il modulo di iscrizione per l'anteprima delle tabelle Iceberg gestite.
Questo tutorial dimostra come utilizzare le transazioni per coordinare gli aggiornamenti tra più istruzioni e tabelle. Si apprenderà entrambe le modalità di transazione: transazioni non interattive, che eseguono il commit automatico e le transazioni interattive, che offrono un controllo esplicito. L'esercitazione illustra anche l'uso di transazioni con procedure memorizzate e script SQL per creare carichi di lavoro di archiviazione dati fondamentali in Azure Databricks.
Requisiti
- Ambiente: accesso a un'area di lavoro di Azure Databricks.
-
Calcolo: i tipi di calcolo supportati variano in base alla modalità transazione:
- Un sql warehouse classico o serverless supporta entrambe le modalità di transazione.
- L'ambiente di calcolo serverless supporta solo transazioni non interattive.
- I cluster classici che eseguono Databricks Runtime 18.0 o versione successiva supportano solo transazioni non interattive.
-
Privilegi:
CREATE TABLEin uno schema del catalogo Unity .
Configurare tabelle di esempio
Tutte le tabelle scritte in in un'istruzione multipla, una transazione a più tabelle deve:
- Essere tabelle gestite dal catalogo Unity (Delta o Iceberg)
- Abilitare commit gestiti dal catalogo
Creare due tabelle di esempio nell'editor SQL o in un notebook:
-- Create a table for account data
CREATE TABLE IF NOT EXISTS sample_accounts (
id INT,
account_name STRING,
balance DECIMAL(10,2)
) USING DELTA
TBLPROPERTIES (
'delta.feature.catalogManaged' = 'supported'
);
-- Create a table for transaction records
CREATE TABLE IF NOT EXISTS sample_transactions (
id INT,
account_id INT,
transaction_type STRING,
amount DECIMAL(10,2)
) USING DELTA
TBLPROPERTIES (
'delta.feature.catalogManaged' = 'supported'
);
-- To upgrade an existing table, use:
-- ALTER TABLE <table_name> SET TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported');
-- Insert sample data
INSERT INTO sample_accounts VALUES
(1, 'Alice', 1000.00),
(2, 'Bob', 500.00);
INSERT INTO sample_transactions VALUES
(1, 1, 'deposit', 100.00);
Verificare la configurazione:
SELECT * FROM sample_accounts;
SELECT * FROM sample_transactions;
Risultato:
sample_accounts:
id account_name balance
1 Alice 1000.00
2 Bob 500.00
sample_transactions:
id account_id transaction_type amount
1 1 deposit 100.00
Transazioni non interattive
Le transazioni non interattive usano BEGIN ATOMIC ... END; la sintassi. Ogni istruzione viene eseguita come singola unità atomica. Se ogni istruzione ha esito positivo, Azure Databricks esegue automaticamente il commit. Se un'istruzione ha esito negativo, Azure Databricks esegue automaticamente il rollback di tutte le modifiche. Per informazioni dettagliate sulla sintassi e sui modelli di utilizzo, vedere Transazioni non interattive.
Eseguire una transazione riuscita
Aggiornare entrambe le tabelle in modo atomico:
BEGIN ATOMIC
-- Update Alice's account balance
UPDATE sample_accounts
SET balance = balance + 100.00
WHERE id = 1;
-- Record the deposit transaction
INSERT INTO sample_transactions
VALUES (2, 1, 'deposit', 100.00);
END;
Verificare che entrambe le operazioni siano riuscite:
-- Alice's balance should now be 1100.00
SELECT * FROM sample_accounts WHERE id = 1;
-- Should show two transaction records
SELECT * FROM sample_transactions;
Sia l'aggiornamento del saldo che il record della transazione sono stati creati insieme. Se una delle due istruzioni non fosse riuscita, nessuna delle modifiche avrebbe eseguito il commit e Databricks avrebbe terminato la transazione senza effetti collaterali.
Usare SIGNAL per interrompere una transazione in una condizione
È possibile usare SIGNAL all'interno di un BEGIN ATOMIC ... END; blocco per interrompere la transazione quando non viene soddisfatta una condizione definita dall'utente. Ciò è utile per la convalida dei dati prima del commit:
BEGIN ATOMIC
-- Insert new account
INSERT INTO sample_accounts VALUES (3, 'Charlie', -50.00);
-- Fail the transaction if balance is negative
IF (SELECT balance FROM sample_accounts WHERE id = 3) < 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Account balance cannot be negative';
END IF;
END;
SIGNAL genera un errore, che causa il rollback automatico dell'intera transazione. Verificare che sia stato eseguito il rollback dell'inserimento:
-- Should return 0 rows (the transaction was rolled back by SIGNAL)
SELECT * FROM sample_accounts WHERE id = 3;
Consultare il rollback automatico in caso di errore
Eseguire una transazione con un'istruzione non valida:
BEGIN ATOMIC
-- This statement is valid
INSERT INTO sample_accounts VALUES (4, 'David', 300.00);
-- This statement will fail (table does not exist)
INSERT INTO non_existent_table VALUES (1, 2, 3);
END;
La transazione fallisce con un errore. Verificare che sia stato eseguito il rollback della prima istruzione:
-- Should return 0 rows because the transaction was rolled back
SELECT * FROM sample_accounts WHERE id = 4;
Anche se la prima INSERT istruzione è valida, è stato eseguito il rollback perché la seconda istruzione non è riuscita. Questa dimostra la garanzia di tutto o niente delle transazioni.
Transazioni interattive
Le transazioni interattive consentono di controllare esplicitamente quando eseguire il commit o il rollback. Usare BEGIN TRANSACTION per avviare, quindi COMMIT per salvare le modifiche o ROLLBACK per eliminarle.
Confermare le modifiche
Avviare una transazione:
BEGIN TRANSACTION;
Apportare modifiche (non ancora eseguito il commit):
INSERT INTO sample_accounts VALUES (5, 'Eve', 850.00);
UPDATE sample_accounts SET balance = balance + 50.00 WHERE id = 2;
Eseguire il commit per rendere permanenti le modifiche:
COMMIT;
Verificare le modifiche:
-- Eve's account should now be visible
SELECT * FROM sample_accounts WHERE id = 5;
-- Bob's balance should be 550.00 (500 + 50)
SELECT * FROM sample_accounts WHERE id = 2;
Eseguire il rollback delle modifiche
Avviare una nuova transazione:
BEGIN TRANSACTION;
Apportare una modifica:
INSERT INTO sample_accounts VALUES (6, 'Frank', 600.00);
Verificare che la modifica sia visibile nella sessione:
-- Should show Frank's account (visible in your session only)
SELECT * FROM sample_accounts WHERE id = 6;
Eseguire il rollback per annullare la modifica:
ROLLBACK;
Verificare che la modifica sia stata rimossa:
-- Should return 0 rows (the insert was rolled back)
SELECT * FROM sample_accounts WHERE id = 6;
Uso con procedure memorizzate e script SQL
È possibile combinare transazioni con stored procedure per creare logica di transazione riutilizzabile. Questo modello è utile per operazioni complesse eseguite di frequente.
Creare due tabelle con la gestione dei commit tramite catalogo abilitata
CREATE TABLE orders (order_id STRING, item_sku STRING, quantity_ordered INT) TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported'); CREATE TABLE inventory (item_sku STRING, quantity_in_stock INT) TBLPROPERTIES ('delta.feature.catalogManaged' = 'supported');Definire la procedura memorizzata
CREATE OR REPLACE PROCEDURE main.retail.apply_order( IN p_order_id STRING, IN p_customer_id STRING, IN p_order_amount DECIMAL(18,2) ) LANGUAGE SQL SQL SECURITY INVOKER MODIFIES SQL DATA AS BEGIN -- Insert the order INSERT INTO main.retail.orders (order_id, customer_id, amount) VALUES (p_order_id, p_customer_id, p_order_amount); -- Update total sales per customer MERGE INTO main.retail.total_sales AS t USING ( SELECT p_customer_id AS customer_id, p_order_amount AS order_amount ) s ON t.customer_id = s.customer_id WHEN MATCHED THEN UPDATE SET t.total_amount = t.total_amount + s.order_amount WHEN NOT MATCHED THEN INSERT (customer_id, total_amount) VALUES (s.customer_id, s.order_amount); END;Definire la transazione
BEGIN ATOMIC -- Staging batch id for this transaction DECLARE new_order_id STRING DEFAULT uuid(); DECLARE v_batch_id STRING DEFAULT uuid(); -- 1) Stage incoming customer and order rows INSERT INTO main.retail.orders_staging (order_id, customer_id, amount, batch_id) VALUES (new_order_id, 'CUST_123', 249.99, v_batch_id); -- 2) Drive final writes from staging to production via stored procedure FOR o AS SELECT order_id, customer_id, amount FROM main.retail.orders_staging WHERE batch_id = v_batch_id DO CALL main.retail.apply_order( o.order_id, o.customer_id, o.amount ); END FOR; -- 3) Clean up processed staging rows DELETE FROM main.retail.orders_staging WHERE batch_id = v_batch_id; END; -- 4) Commit the transaction
Se una parte della transazione ha esito negativo, Databricks esegue automaticamente il rollback di tutte le modifiche.
Eseguire la pulizia
Rimuovere le tabelle di esempio:
DROP TABLE IF EXISTS sample_accounts;
DROP TABLE IF EXISTS sample_transactions;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS inventory;
Passaggi successivi
- Transazioni: panoramica del supporto delle transazioni.
- Modalità di transazione: sintassi dettagliata e modelli per entrambe le modalità.
- Commit gestiti dal catalogo: Abilita il supporto delle transazioni nelle tue tabelle.
- Usare transazioni di client diversi: eseguire transazioni da applicazioni JDBC, ODBC e Python.