Níveis de isolamento (WriteSerializable e Serializable)
Delta Lake no Databricks suporta dois níveis de isolamento que controlam como as operações concorrentes em uma determinada tabela interagem:
isolationLevel | Descrição |
|---|---|
Serializável | O nível de isolamento mais alto. Garante que as operações de escrita confirmadas e todas as leituras sejam serializáveis. As operações são permitidas desde que haja uma sequência serial que, quando executada uma de cada vez, gere o mesmo resultado apresentado na tabela. Para operações de escrita, essa sequência serial é a mesma que a ordem vista no histórico da tabela. |
WriteSerializable (padrão) | Um nível de isolamento mais fraco do que o Serializable. Garante que apenas as operações de escrita (e não as de leitura) sejam serializáveis. Isso ainda é mais robusto do que o isolamento do Snapshot . Proporciona um bom equilíbrio entre consistência e disponibilidade de dados para a maioria das operações comuns. |
Como os níveis de isolamento afetam as leituras
As operações de leitura sempre utilizam o isolamento de Snapshot. O nível de isolamento de escrita determina se um leitor pode ver um instantâneo de uma tabela que, segundo a história, "nunca existiu".
- Serializável : O leitor sempre vê apenas as tabelas que se conformam à narrativa.
- WriteSerializable : Um leitor pode ver um estado de tabela que não existe no log Delta.
Exemplo: excluir e inserir concorrente
Considere um cenário onde uma transação de exclusão de longa duração e uma transação de inserção começam ao mesmo tempo e leem a versão v0. A transação de inserção é confirmada primeiro e cria a versão v1. Depois disso, a transação de exclusão tenta commit v2:
t0: deleteTxn_START
t1: insertTxn_START
t2: insertTxn_COMMIT(v1)
t3: deleteTxn_COMMIT(v2)
Neste cenário, deleteTxn não viu os dados inseridos por insertTxn e não os apagou:
- Serializable :
deleteTxnnão tem permissão para commit e ocorre um conflito. - WriteSerializable :
deleteTxntem permissão para commit porque as transações podem ser ordenadas. O estado da tabela resultante é como seinsertTxntivesse ocorrido depois dedeleteTxn, portanto, as linhas inseridas fazem parte da tabela. No entanto, o histórico Delta mostra a ordem física commit (insertTxnem v1 antesdeleteTxnem v2).
Defina o nível de isolamento
Defina o nível de isolamento usando o comando ALTER TABLE :
ALTER TABLE <table-name> SET TBLPROPERTIES ('delta.isolationLevel' = <level-name>)
Onde <level-name> é Serializable ou WriteSerializable.
Exemplo:
-- Change from default WriteSerializable to Serializable
ALTER TABLE my_table SET TBLPROPERTIES ('delta.isolationLevel' = 'Serializable')
Quando é que Delta Lake commit sem consultar a tabela?
As operações Delta Lake INSERT ou append não leem o estado da tabela antes do commit se as seguintes condições forem satisfeitas:
- A lógica é expressa usando lógica SQL
INSERTou modo de acréscimo. - A lógica não contém subconsultas ou condicionais que façam referência à tabela alvo das operações de gravação.
Assim como em outros commits, Delta Lake usa metadados log de transações para validar e resolver as versões das tabelas no momento commit, mas nenhuma versão da tabela é realmente lida.
Muitos padrões comuns usam operações MERGE para inserir dados com base nas condições da tabela. Embora possa ser possível reescrever essa lógica usando instruções INSERT , se alguma expressão condicional fizer referência a uma coluna na tabela de destino, essas instruções terão as mesmas limitações de concorrência que MERGE.