Qual é o efeito de ter uma transação aberta no MSSQL por muito tempo?

11

Só estou imaginando o que acontece se você iniciar uma transação em um banco de dados e se esquecer de confirmar ou reverter isso. O servidor estará inoperante? Vamos dizer que você deixou por 3 dias.

Também existem usuários que estão usando, assumindo que os outros usuários não sabiam que há uma transação não fechada (vamos supor que os usuários estão apenas inserindo dados no banco de dados). Quais são as conseqüências dessa ação?

JanLeeYu
fonte

Respostas:

14

Ter uma transação aberta por si só não terá quase nenhuma conseqüência. Um simples

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

na pior das hipóteses, conterá alguns bytes de valores de status. Nada demais.

A maioria dos programas fará um trabalho real dentro da transação e isso é outra questão. O objetivo de uma transação é garantir que vários fatos no banco de dados sejam verdadeiros simultaneamente, apesar de haver outros usuários gravando no mesmo banco de dados simultaneamente.

Veja o exemplo canônico de transferência de dinheiro entre contas bancárias. O sistema deve garantir que a conta de origem exista, tenha fundos suficientes, a conta de destino e que o débito e o crédito ocorram ou não. Ele deve garantir isso enquanto outras transações acontecem, talvez até entre essas duas contas. O sistema garante isso bloqueando as tabelas em questão. Quais bloqueios são feitos e quanto do trabalho de outras pessoas você vê, é controlado pelo nível de isolamento da transação .

Portanto, se você trabalha muito, há uma boa chance de outras transações ficarem na fila aguardando os objetos nos quais você mantém bloqueios. Isso reduzirá a taxa de transferência geral do sistema. Eventualmente, eles atingem os limites de tempo limite e falham, o que é um problema para o comportamento geral do sistema. Se você usar um nível de isolamento otimista, sua transação poderá falhar ao tentar uma confirmação por causa do trabalho de outras pessoas.

Manter bloqueios consome recursos do sistema. Esta é a memória que o sistema não pode usar para processar outras solicitações, reduzindo a taxa de transferência.

Se muito trabalho foi realizado, o sistema pode optar por executar a escalação de bloqueios . Em vez de bloquear linhas individuais, a tabela inteira será bloqueada. Em seguida, mais usuários simultâneos serão afetados, a taxa de transferência do sistema cairá ainda mais e o impacto do aplicativo será maior.

As alterações de dados são gravadas no arquivo de log, assim como os bloqueios que os protegem. Eles não podem ser limpos do log até que a transação seja confirmada. Portanto, transações muito longas podem causar inchaço no arquivo de log com seus problemas associados.

Se o trabalho atual usar tempdb, o que é provável para grandes cargas de trabalho, os recursos podem estar vinculados até o final da transação. Em casos extremos, isso pode causar falhas em outras tarefas, porque não há mais espaço suficiente para elas. Eu tive casos em que um UPDATE mal codificado preencheu o tempdb, portanto não havia disco suficiente para a classificação de um relatório e o relatório falhou.

Se você optar por ROLLBACK a transação, ou o sistema falhar e se recuperar, o tempo necessário para que o sistema fique disponível novamente dependerá de quanto trabalho foi executado. Simplesmente abrir uma transação não afetará o tempo de recuperação; é quanto trabalho foi realizado. Se a transação foi aberta, mas ociosa por uma hora, a recuperação será quase instantânea. Se ele estava escrevendo constantemente para aquela hora, a regra geral é que o tempo de recuperação também será de cerca de uma hora.

Como você pode ver, transações longas podem ser problemáticas. Para sistemas OLTP, a melhor prática é ter uma transação de banco de dados por transação comercial. Para entrada do processo de trabalho em lote em blocos, com confirmações frequentes e reinicie o código lógico. Normalmente, milhares de registros podem ser processados ​​em uma única transação de banco de dados, mas isso deve ser testado quanto à simultaneidade e reavaliar o consumo.

Não fique tentado a ir ao outro extremo e evitar completamente transações e bloqueios. Se você precisar manter a consistência dos seus dados (e por que mais você usaria um banco de dados?), Os níveis e as transações de isolamento servirão a um propósito muito importante. Aprenda sobre suas opções e decida com qual equilíbrio de simultaneidade e correção você está preparado para viver para cada parte do seu aplicativo.

Michael Green
fonte
mesmo se estiver aberto por três dias?
27416 JanLeeYu
Sim, mesmo por três dias. O ponto importante é a quantidade de trabalho que foi realizado enquanto o TX está aberto, e não apenas por quanto tempo ele está aberto. Obviamente, como DBA, você pode perguntar ao proprietário da transação por que eles precisam ficar abertos por tanto tempo. Quando dirigi uma equipe de DBA, registrei todo o TX aberto por mais de 30 minutos e tive uma conversa com o proprietário.
Michael Green
ESTÁ BEM. Obrigado pela ótima explicação. Embora todos também tenham se saído bem.
JanLeeYu
Que alívio ... Mais uma vez obrigado pela resposta.
JanLeeYu
"UPDATE mal codificado" Sim. Visto isso. Uma instrução de atualização dentro de um loop que não qualificou alguns nomes e resultou em um comportamento semelhante a 1 = 1; portanto, atualizou a tabela inteira para cada iteração do loop (que também colocou os dados incorretos na maioria dessas linhas também).
Jpmc26 27/06
6

Sua maior consequência será o bloqueio dos objetos usados ​​na transação. Especialmente se você assumir que seus usuários estão inserindo dados, essa transação de longa execução pode incluir instruções SELECT em tabelas usadas com frequência. As instruções de atualização de seus usuários podem não conseguir o bloqueio necessário para concluir suas atualizações ou inserções.

Uma coisa secundária que poderia acontecer é a atividade do arquivo de log, por exemplo, se você estava atualizando um grande conjunto de dados, a parte do log que a transação está usando é mantida ativa durante a transação. Você não poderá reutilizar essa parte do log até que a transação seja confirmada ou revertida. Nos cenários em que você pode estar em um sistema OLTP altamente ativo, isso pode fazer com que seu arquivo de log cresça rapidamente, enchendo seu dispositivo de armazenamento.

Andriy M
fonte
por exemplo, quem criou a transação está desconectado do servidor, será capaz de efetuar login novamente no servidor novamente para fechar a transação?
JanLeeYu
Depende, se a transação estivesse em um ambiente que usasse o MSDTC, poderia ser uma transação órfã. Nesse caso, o usuário não seria mais capaz de fechá-lo por conta própria ... o DBA precisaria intervir para lidar com isso. Fora isso, você geralmente verá a transação ser cancelada pelo SQL Server quando for desconectada ... mas novamente em grandes transações que podem não ser o caso toda vez.
Caso isso aconteça, o administrador ainda poderá fechar a transação, certo?
JanLeeYu
Não posso responder a isso, tudo depende. Eu tive casos em que o servidor teve que ser reiniciado ou a instância falhou no nó / réplica secundário.
4

Transações incompletas podem conter um grande número de bloqueios e causar o bloqueio

Quando uma transação não é concluída porque uma consulta atinge o tempo limite ou porque o lote é cancelado no meio de uma transação sem emitir uma instrução COMMIT ou ROLLBACK para concluir a transação, a transação é deixada aberta e todos os bloqueios adquiridos durante a transação continuam. a ser realizada. As transações subsequentes executadas na mesma conexão são tratadas como transações aninhadas, portanto, todos os bloqueios adquiridos nessas transações concluídas não são liberados. Esse problema se repete com todas as transações executadas da mesma conexão até que um ROLLBACK seja executado. Como resultado, um grande número de bloqueios é mantido, os usuários são bloqueados e as transações são perdidas, o que resulta em dados diferentes do que você espera.

fonte

Pimp Juice IT
fonte
por exemplo, quem criou a transação está desconectado do servidor, será capaz de efetuar login novamente no servidor novamente para fechar a transação?
JanLeeYu
Quando o SQL Server souber que a conexão foi perdida, ela reverterá a transação. Consulte aqui dba.stackexchange.com/questions/47404/… . Se o mesmo usuário se reconectar, será uma sessão diferente e, portanto, não poderá "adotar" a transação antiga.
Michael Green