Tutorial: Coordenar transações entre tabelas
Visualização
Transações que gravam no Unity Catalog gerenciam tabelas Delta e estão em Pré-visualização Pública.
Transações que gravam em tabelas Iceberg gerenciadas Unity Catalog estão em Pré-visualização Privada. Para join desta pré-visualização, envie o formulário de inscrição para a pré-visualização das mesas Iceberg.
Este tutorial demonstra como usar transações para coordenar atualizações em várias instruções e tabelas. Você aprenderá os dois modos de transação: transações não interativas, que commit automaticamente, e transações interativas, que lhe dão controle explícito. O tutorial também demonstra o uso de transações com procedimentos armazenados e scripts SQL para criar cargas de trabalho de armazenamento de dados de missão crítica no Databricks.
Requisitos
-
Ambiente : Acesso a um workspace Databricks .
-
Computação : Os tipos compute suportados variam de acordo com o modo de transação:
- Um SQL warehouse clássico ou serverless suporta ambos os modos de transação.
- computesem servidor suporta apenas transações não interativas.
- clusters clássicos que executam Databricks Runtime 18.0 ou superior suportam apenas transações não interativas.
-
Privilégios :
CREATE TABLEem um esquema Unity Catalog .
Configure tabelas de exemplo
Todas as tabelas que são gravadas em uma transação com várias instruções e várias tabelas devem:
- Unity Catalog gerenciar tabelas (Delta ou Iceberg)
- Ative a opção de confirmação Catalog-gerenciar
Crie duas tabelas de exemplo no EditorSQL ou em um 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);
Verifique a configuração:
SELECT * FROM sample_accounts;
SELECT * FROM sample_transactions;
Saída:
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
Transações não interativas
Transações não interativas usam a sintaxe BEGIN ATOMIC ... END; . A execução de todas as instruções ocorre como uma única unidade atômica. Se todas as instruções forem bem-sucedidas, o Databricks realiza o commit automaticamente. Se alguma instrução falhar, o Databricks reverte todas as alterações automaticamente. Para obter detalhes sobre a sintaxe e os padrões de uso, consulte transações não interativas.
execução de uma transação bem-sucedida
Atualize ambas as tabelas atomicamente:
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;
Verifique se ambas as operações foram bem-sucedidas:
-- Alice's balance should now be 1100.00
SELECT * FROM sample_accounts WHERE id = 1;
-- Should show two transaction records
SELECT * FROM sample_transactions;
A atualização do saldo e o registro da transação foram criados simultaneamente. Se alguma das instruções tivesse falhado, nenhuma das alterações teria sido confirmada e o Databricks teria encerrado a transação sem efeitos colaterais.
Use SIGNAL para interromper uma transação sob uma condição.
Você pode usar SIGNAL dentro de um bloco BEGIN ATOMIC ... END; para falhar a transação quando uma condição definida pelo usuário não for atendida. Isso é útil para validação de dados antes do 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;
O SIGNAL gera um erro, o que faz com que toda a transação seja revertida automaticamente. Verifique se o inserto foi revertido:
-- Should return 0 rows (the transaction was rolled back by SIGNAL)
SELECT * FROM sample_accounts WHERE id = 3;
Consulte a seção sobre reversão automática em caso de falha.
executar uma transação com uma instrução invá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;
A transação falhou com um erro. Verifique se a primeira instrução foi revertida:
-- Should return 0 rows because the transaction was rolled back
SELECT * FROM sample_accounts WHERE id = 4;
Embora a primeira instrução INSERT fosse válida, ela foi revertida porque a segunda instrução falhou. Isso demonstra a garantia de "tudo ou nada" das transações.
Transações interativas
Transações interativas oferecem controle explícito sobre quando commit ou reverter a transação. Use BEGIN TRANSACTION para iniciar e, em seguida, confirme para salvar as alterações ou ROLLBACK para descartá-las.
confirmar alterações
Iniciar uma transação:
BEGIN TRANSACTION;
Fazer alterações (ainda não confirmadas):
INSERT INTO sample_accounts VALUES (5, 'Eve', 850.00);
UPDATE sample_accounts SET balance = balance + 50.00 WHERE id = 2;
Comprometa-se a tornar as mudanças permanentes:
COMMIT;
Verifique as alterações:
-- 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;
Reverter alterações
Iniciar uma nova transação:
BEGIN TRANSACTION;
Faça uma mudança:
INSERT INTO sample_accounts VALUES (6, 'Frank', 600.00);
Verifique se a alteração está visível na sua sessão:
-- Should show Frank's account (visible in your session only)
SELECT * FROM sample_accounts WHERE id = 6;
Reverter para descartar a alteração:
ROLLBACK;
Verifique se a alteração foi descartada:
-- Should return 0 rows (the insert was rolled back)
SELECT * FROM sample_accounts WHERE id = 6;
Utilizar com procedimentos armazenados e scripts SQL.
Você pode combinar transações com procedimentos armazenados para criar uma lógica de transação reutilizável. Este padrão é útil para operações complexas que você executa com frequência.
-
Crie duas tabelas com o comando `catalog-gerenciar commit` ativado.
SQL
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'); -
Defina o procedimento armazenado
SQLCREATE 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; -
Defina a transação
SQLBEGIN 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 alguma parte da transação falhar, o Databricks reverte todas as alterações automaticamente.
Limpar
Remova as tabelas de exemplo:
DROP TABLE IF EXISTS sample_accounts;
DROP TABLE IF EXISTS sample_transactions;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS inventory;
Próximos passos
- Transações: Visão geral do suporte a transações.
- Modos de transação: Sintaxe e padrões detalhados para ambos os modos.
- Catalog-gerenciar commit: Habilite o suporte a transações em suas tabelas.
- Utilize transações de diferentes clientes: execute transações de aplicações JDBC, ODBC e Python .