Estou pensando em aplicar durabilidade atrasada em um sistema em que trabalho e quero ter certeza de que tenho o modelo mental correto para evitar perda de dados. Meu entendimento é que basicamente significa COMMIT
se transformar em uma espécie de "gato de Schrodinger" entre COMMIT
e ROLLBACK
, certo? Em outras palavras, algumas transações que são confirmadas podem acabar sendo revertidas ("a confirmação é uma mentira").
Portanto, não devemos esperar ver nenhuma perda de dados em cenários como o seguinte:
- Um procedimento de ativação do service broker que
RECEIVE
s mensagens, as processa dentro de uma transação eCOMMIT
s. Se "a confirmação for uma mentira" e a transação não for realmente confirmada, será uma reversão e o service broker a executará automaticamente novamente. - Um trabalho periódico do tipo ETL que importa arquivos em massa para uma tabela de preparo (essa parte seria totalmente durável). Depois, dentro de uma transação, ele processa os dados encenados e marca os dados encenados como processados. Se "o commit for uma mentira" e a transação não for realmente confirmada, será um rollback e os dados testados não serão marcados como processados, então faremos isso novamente na próxima vez.
Nesses cenários, não esperaríamos perda real de dados porque as transações são executadas novamente automaticamente. Nesse caso, não é mais arriscado do que qualquer outra coisa que possa interromper uma transação (por exemplo, um deadlock ou um desligamento não planejado que interrompa o processo).
Por outro lado, um cenário como o seguinte não seria um bom candidato para durabilidade atrasada e arriscaria a perda de dados:
- Um processo externo (por exemplo, SSIS), para cada arquivo em um diretório, inicia uma transação, importa em massa os dados do arquivo e confirma a transação. Depois que a transação é confirmada, ele exclui o arquivo. Agora, se "o commit for uma mentira" e a transação não for realmente confirmada, teremos perdido os dados do arquivo para sempre porque excluímos o arquivo, mas a importação foi revertida.
Portanto, em suma, a durabilidade atrasada pode perder dados apenas se alguma parte externa estiver confiando no COMMIT
. Por exemplo, um checkout online insere uma venda e assume razoavelmente que, quando os dados foram confirmados, a venda foi concluída etc., e informa o usuário como tal. Mas se for algum processamento que já pode tolerar e retomar automaticamente a partir de interrupções/reversões, não deve haver risco aumentado.
Isso soa certo?
Receio que você tenha entendido mal como funcionam as transações com durabilidade atrasada. Não haverá uma reversão mágica após uma confirmação bem-sucedida - o aplicativo cliente não saberá se as alterações que acredita terem sido confirmadas nunca persistiram. Conforme descrito na documentação , no modo de durabilidade atrasada, o servidor relata uma confirmação bem-sucedida imediatamente, mas atrasa a gravação do buffer de log no disco até algum tempo depois. Se o servidor travar ou desligar antes disso, essas alterações serão perdidas e o cliente não saberá disso.
Isso é basicamente correto.
Se uma transação estiver lendo do banco de dados e gravando no banco de dados, e você tiver algum mecanismo para tentar novamente a transação se ela for revertida, não haverá perda de dados com durabilidade atrasada.
Mas em ambos os cenários que você descreve, duvido que a durabilidade atrasada seja útil. A durabilidade atrasada pode melhorar o rendimento onde uma sessão está confirmando um grande número de pequenas transações, eliminando a liberação de log na confirmação. No exemplo do Service Broker, a transação deve ter como escopo um lote de mensagens para reduzir a frequência de confirmação. E no exemplo de ETL você tem uma transação grande, portanto, eliminar a liberação de log único na confirmação no final provavelmente não será uma melhoria significativa.
Se um cliente estiver gravando novos dados no banco de dados com durabilidade atrasada, pode haver perda de dados.