Concorrência ao nível das linhas

A concorrência ao nível das linhas reduz conflitos entre operações de escrita concorrentes ao detetar alterações ao nível da linha e ao resolver automaticamente conflitos que ocorrem quando escritas concorrentes atualizam ou eliminam diferentes linhas no mesmo ficheiro de dados.

Requisitos para concorrência ao nível de linha

A concorrência ao nível da linha é automaticamente ativada quando todos os seguintes requisitos são cumpridos:

  • A utilizar o Databricks Runtime 14.3 LTS ou superior.
  • A tabela de origem não usa partições.
  • A tabela de origem tem vetores de eliminação ativados. Ver Vetores de eliminação em Databricks.

As tabelas particionadas não permitem concorrência ao nível das linhas. No entanto, quando os vetores de eliminação estão ativados, as tabelas particionadas ainda podem evitar conflitos entre OPTIMIZE e operações de escrita. Consulte Limitações para simultaneidade em nível de linha.

Para versões de Runtime Databricks anteriores à 14.3 LTS, veja Comportamento legado de concorrência ao nível de linha.

Matriz de conflito com concorrência ao nível das linhas

Para tabelas de origem com concorrência ao nível da linha, a tabela seguinte mostra quais pares de operações de escrita podem entrar em conflito em cada nível de isolamento:

Operation INSERT (1) UPDATE, EXCLUIR, MERGE INTO OPTIMIZE
INSERT Não pode entrar em conflito
UPDATE, EXCLUIR, MERGE INTO Não pode haver conflito em WriteSerializable. Pode entrar em conflito em Serializable ao modificar a mesma linha. Pode entrar em conflito ao modificar a mesma linha de dados.
OPTIMIZE Não pode entrar em conflito Pode entrar em conflito quando ZORDER BY é usado. Não pode haver conflito de outra forma. Pode entrar em conflito quando ZORDER BY é usado. Não pode haver conflito de outra forma.

(1) Todas INSERT as operações nesta tabela descrevem operações de adição que não contêm subconsultas que leem dados da mesma tabela. INSERT Operações que contêm subconsultas que leem da mesma tabela suportam a mesma concorrência que MERGE.

Observação

  • Tabelas com colunas de identidade não suportam transações concorrentes. Ver colunas de Identidade.
  • REORG As operações têm a mesma semântica de isolamento que OPTIMIZE quando reescrevem ficheiros de dados. Quando você usa REORG para aplicar uma atualização, os protocolos de tabela são alterados, o que entra em conflito com todas as operações em andamento.

Conflitos de escrita sem concorrência ao nível da linha

Para tabelas de origem sem concorrência ao nível das linhas, a tabela seguinte mostra quais pares de operações de escrita podem entrar em conflito em cada nível de isolamento:

Operation INSERT (1) UPDATE, EXCLUIR, MERGE INTO OPTIMIZE
INSERT Não pode entrar em conflito
UPDATE, EXCLUIR, MERGE INTO Não pode haver conflito em WriteSerializable. Pode entrar em conflito em Serializable. Veja Evitar conflitos usando particionamento. Pode entrar em conflito em Serializable e WriteSerializable. Veja Evitar conflitos usando particionamento.
OPTIMIZE Não pode entrar em conflito Não pode entrar em conflito em tabelas com vetores de eliminação ativados, a menos que ZORDER BY seja utilizado. Pode entrar em conflito de outra forma. Não pode entrar em conflito em tabelas com vetores de eliminação ativados, a menos que ZORDER BY seja utilizado. Pode entrar em conflito de outra forma.

(1) Todas INSERT as operações nesta tabela descrevem operações de adição que não contêm subconsultas que leem dados da mesma tabela. INSERT Operações que contêm subconsultas que leem da mesma tabela suportam a mesma concorrência que MERGE.

Observação

  • Tabelas com colunas de identidade não suportam transações concorrentes. Ver colunas de Identidade.
  • REORG As operações têm a mesma semântica de isolamento que OPTIMIZE quando reescrevem ficheiros de dados. Quando se aplica REORG uma atualização, os protocolos da tabela mudam e entram em conflito com todas as operações em andamento.

Limitações para simultaneidade em nível de linha

Limitações aplicam-se para concorrência a nível de linha. Para as operações seguintes, a resolução de conflitos segue a concorrência normal para conflitos de escrita. Consulte Escrever conflitos sem concorrência ao nível da linha.

Limitação Descrição
Orações condicionais complexas Condições em tipos de dados complexos (structs, arrays, maps), expressões não determinísticas, subconsultas e subconsultas correlacionadas
MERGE requisito de predicado No Databricks Runtime 14.2, MERGE os comandos devem usar um predicado explícito na tabela de destino para filtrar as linhas que correspondem à tabela de origem
Troca de desempenho A deteção de conflitos ao nível da linha pode aumentar o tempo total de execução. Com muitas transações simultâneas, o autor prioriza a latência em detrimento da resolução de conflitos

Todas as limitações para vetores de exclusão também se aplicam. Consulte Limitações.

Evitar conflitos usando particionamento

Para todos os casos marcados como "podem entrar em conflito" nas matrizes de conflito, um conflito ocorre apenas se as duas operações afetarem o mesmo conjunto de ficheiros. Para tornar dois conjuntos de ficheiros disjuntos, particione a tabela pelas mesmas colunas usadas nas condições de operação.

Exemplo:

Os comandos UPDATE table WHERE date > '2010-01-01' ... e DELETE table WHERE date < '2010-01-01' entram em conflito se a tabela não estiver particionada por data, porque ambos podem tentar modificar os mesmos ficheiros. Dividir a tabela por date evita o conflito.

Observação

Dividir uma tabela por uma coluna com alta cardinalidade pode levar a problemas de desempenho devido ao grande número de subdiretórios.

Evitar conflitos com filtros de partição explícitos

Esta exceção ocorre frequentemente durante operações simultâneas DELETE, UPDATE ou MERGE que podem ler a mesma partição, mesmo quando atualizam partições diferentes. Torne a separação explícita na condição de operação:

// Problem: Condition can scan the entire table
deltaTable.as("t").merge(
    source.as("s"),
    "s.user_id = t.user_id AND s.date = t.date AND s.country = t.country")
  .whenMatched().updateAll()
  .whenNotMatched().insertAll()
  .execute()

// Solution: Add explicit partition filters
deltaTable.as("t").merge(
    source.as("s"),
    "s.user_id = t.user_id AND s.date = t.date AND s.country = t.country AND t.date = '" + date + "' AND t.country = '" + country + "'")
  .whenMatched().updateAll()
  .whenNotMatched().insertAll()
  .execute()

Exceções de conflitos

Quando ocorre um conflito de transação, observa uma das seguintes exceções:

ConcurrentAppendException

Essa exceção ocorre quando uma operação simultânea adiciona arquivos na mesma partição (ou em qualquer lugar em uma tabela não particionada) que sua operação lê. As adições de arquivo podem ser causadas por INSERT, DELETE, UPDATE, ou MERGE operações.

Com o nível de isolamento predefinido WriteSerializable, os ficheiros adicionados por operações INSERT que acrescentam dados sem ler quaisquer dados não entram em conflito com qualquer operação. Se o nível de isolamento for Serializável, quaisquer anexos podem entrar em conflito.

Importante

INSERT operações podem entrar em conflito no modo WriteSerializable se múltiplas operações simultâneas DELETE, UPDATE ou MERGE puderem referenciar valores acrescentados pela operação INSERT. Para evitar isto:

  • Assegura-te de que as operações concorrentes DELETE, UPDATE, ou MERGE não leem os dados anexos
  • Tenha no máximo uma operação DELETE, UPDATE, ou MERGE que possa ler os dados anexados

ConcurrentDeleteReadException

Esta exceção ocorre quando uma operação concorrente apaga um ficheiro que a sua operação leu. As causas comuns são DELETE, UPDATE, ou MERGE operações que reescrevem ficheiros.

ConcurrentDeleteDeleteException

Esta exceção ocorre quando uma operação concorrente apaga um ficheiro que a sua operação também elimina. Isto pode ser causado por duas operações de compactação simultâneas que reescrevem os mesmos ficheiros.

MetadataChangedException

Essa exceção ocorre quando uma transação simultânea atualiza os metadados de uma tabela Delta. As causas comuns são ALTER TABLE operações ou escritas que atualizam o esquema da tabela.

Exceção de Transação Concorrente

Esta exceção ocorre se uma consulta de streaming usando a mesma localização de checkpoint for iniciada várias vezes simultaneamente e tentar escrever na tabela Delta ao mesmo tempo. Nunca execute em simultâneo duas consultas de streaming utilizando a mesma localização de checkpoint.

ProtocolChangedException

Esta exceção pode ocorrer quando:

  • A sua tabela Delta Lake é atualizada para uma nova versão do protocolo (pode precisar de atualizar o seu Databricks Runtime)
  • Vários escritores estão a criar ou substituir uma tabela ao mesmo tempo
  • Vários escritores estão a escrever para um diretório vazio simultaneamente.

Consulte Compatibilidade de recursos e protocolos do Delta Lake.

Comportamento legado de concorrência ao nível das linhas

No Databricks Runtime 13.3 LTS, a concorrência ao nível da linha utiliza comportamento legado:

Recursos adicionais