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.