Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Importante
Las transacciones que escriben en tablas delta administradas por el catálogo de Unity se encuentran en versión preliminar pública.
Las transacciones que escriben en las tablas Iceberg gestionadas por Unity Catalog se encuentran en versión preliminar privada. Para unirse a esta versión preliminar, envíe el formulario de inscripción de las tablas Iceberg administradas.
En este tutorial se muestra cómo usar transacciones para coordinar las actualizaciones entre varias instrucciones y tablas. Aprenderá ambos modos de transacción: transacciones no interactivas, que se confirman automáticamente y transacciones interactivas, lo que proporciona control explícito. En el tutorial también se muestra el uso de transacciones con procedimientos almacenados y scripting de SQL para crear cargas de trabajo de almacenamiento críticas en Azure Databricks.
Requisitos
- Entorno: acceso a un área de trabajo de Azure Databricks.
-
Proceso: los tipos de proceso admitidos varían según el modo de transacción:
- Un almacenamiento de SQL clásico o sin servidor admite ambos modos de transacción.
- El proceso sin servidor solo admite transacciones no interactivas.
- Los clústeres clásicos que ejecutan Databricks Runtime 18.0 o superior solo admiten transacciones no interactivas.
-
Privilegios:
CREATE TABLEen un esquema de catálogo de Unity .
Configuración de tablas de ejemplo
Todas las tablas escritas en en una transacción de varias instrucciones y varias tablas deben:
- Las tablas gestionadas por Unity Catalog (Delta o Iceberg)
- Tener habilitadas las confirmaciones administradas por catálogo
Cree dos tablas de ejemplo en el Editor de SQL o en un cuaderno:
-- 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);
Compruebe la configuración:
SELECT * FROM sample_accounts;
SELECT * FROM sample_transactions;
Salida:
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
Transacciones no interactivas
Las transacciones no interactivas usan BEGIN ATOMIC ... END; sintaxis. Todas las instrucciones se ejecutan como una sola unidad atómica. Si cada instrucción se realiza correctamente, Azure Databricks realiza un commit automáticamente. Si se produce un error en alguna instrucción, Azure Databricks revierte todos los cambios automáticamente. Para obtener información detallada sobre la sintaxis y los patrones de uso, consulte transacciones no interactivas.
Realizar una transacción exitosa
Actualice ambas tablas de forma atómica:
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;
Compruebe que ambas operaciones se han realizado correctamente:
-- Alice's balance should now be 1100.00
SELECT * FROM sample_accounts WHERE id = 1;
-- Should show two transaction records
SELECT * FROM sample_transactions;
Tanto la actualización del saldo como el registro de transacciones se crearon juntos. Si se hubiera producido un error en cualquiera de las instrucciones, ningún cambio habría sido confirmado y Databricks habría terminado la transacción sin consecuencias.
Uso de SIGNAL para generar un error en una transacción bajo una condición
Puede usar SIGNAL dentro de un BEGIN ATOMIC ... END; bloque para producir un error en la transacción cuando no se cumple una condición definida por el usuario. Esto es útil para la validación de datos antes de proceder:
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 error, que hace que toda la transacción se revierte automáticamente. Compruebe que la inserción fue revertida:
-- Should return 0 rows (the transaction was rolled back by SIGNAL)
SELECT * FROM sample_accounts WHERE id = 3;
Consulte reversión automática en caso de error.
Ejecute una transacción con una declaración no válida:
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;
Se produce un error en la transacción. Compruebe que la primera instrucción se revierte:
-- Should return 0 rows because the transaction was rolled back
SELECT * FROM sample_accounts WHERE id = 4;
Aunque la primera INSERT instrucción era válida, se reviertó porque se produjo un error en la segunda instrucción. Esto muestra la garantía todo o nada de las transacciones.
Transacciones interactivas
Las transacciones interactivas proporcionan control explícito sobre cuándo confirmar o revertir. Use BEGIN TRANSACTION para iniciar y, a continuación, COMMIT para guardar los cambios o ROLLBACK para descartarlos.
Confirmar cambios
Inicie una transacción:
BEGIN TRANSACTION;
Realizar cambios (aún no confirmados):
INSERT INTO sample_accounts VALUES (5, 'Eve', 850.00);
UPDATE sample_accounts SET balance = balance + 50.00 WHERE id = 2;
Comprometerse a hacer permanentes los cambios:
COMMIT;
Compruebe los cambios:
-- 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;
Revertir los cambios
Inicie una nueva transacción:
BEGIN TRANSACTION;
Realice un cambio:
INSERT INTO sample_accounts VALUES (6, 'Frank', 600.00);
Compruebe que el cambio está visible en la sesión:
-- Should show Frank's account (visible in your session only)
SELECT * FROM sample_accounts WHERE id = 6;
Revierte para descartar el cambio:
ROLLBACK;
Compruebe que se ha descartado el cambio:
-- Should return 0 rows (the insert was rolled back)
SELECT * FROM sample_accounts WHERE id = 6;
Uso con procedimientos almacenados y scripts de SQL
Puede combinar transacciones con procedimientos almacenados para crear lógica de transacción reutilizable. Este patrón es útil para operaciones complejas que se ejecutan con frecuencia.
Creación de dos tablas con confirmaciones administradas por catálogo habilitadas
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');Definición del procedimiento almacenado
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;Definición de la transacción
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
Si se produce un error en alguna parte de la transacción, Databricks revierte todos los cambios automáticamente.
Limpiar
Quite las tablas de ejemplo:
DROP TABLE IF EXISTS sample_accounts;
DROP TABLE IF EXISTS sample_transactions;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS inventory;
Pasos siguientes
- Transacciones: información general sobre la compatibilidad con transacciones.
- Modos de transacción: sintaxis detallada y patrones para ambos modos.
- Confirmaciones administradas por catálogo: habilite la compatibilidad con transacciones en las tablas.
- Usar transacciones de diferentes clientes: ejecute transacciones desde aplicaciones JDBC, ODBC y Python.