Qualquer transação aberta ativa fixará o log, impedindo o truncamento e, eventualmente, causando crescimento. Se você iniciar uma transação, escreva no log e espere eternamente na esperança de que uma mensagem eventualmente acorde, você acabou de fixar o log e fazer com que ele cresça.
Ultimamente, comecei a recomendar que as pessoas evitassem o WAITFOR no procedimento ativado, junto com o loop. Apenas emita um RECIEVe e pronto, deixe o mecanismo de ativação girar para você (ele faz) e não espere, simplesmente RECEIVE.
O sabor WAITFOR de RECEIVE cria um ponto de salvamento internamente. Isso gera log (pelo menos 3 registros de log) e, de fato, fixa o log no local enquanto aguarda. Ter um tempo limite longo do WAITFOR (ou pior, um tempo infinito) seria uma prática muito ruim.
Iria WAITFOR (...) TIMEOUT 3600000resolver o problema? Por exemplo, liberar a cada hora.
AngryHacker
2
Seu log crescerá muito em uma hora. WAITFOR (REC EIVE) destina-se a intervalos como 5 segundos ...
Remus Rusanu
11
Você também deve investigar por que sua transação está realmente ativa (possui registro escrito). O padrão típico do Service Broker não emite nenhuma gravação antes do RECEIVE.
Remus Rusanu
11
Não entendo seu último comentário. A transação está ativa porque emiti um WAITFOR (RECEIVE...Você poderia expandir? Talvez eu tenha entendido errado.
AngryHacker
8
begin transaction; waitfor(receive...)não gerará nenhum registro de log (não 'ativará' a transação) enquanto aguarda e, portanto, não fixará o log. Somente begin transaction;[insert|update|delete];waitfor(receive...)fará com que a transação seja 'ativada' (gerar registros de log) e, portanto, realmente fixará o log enquanto aguarda.
Remus Rusanu
5
No SQL Server 2008 R2, se eu executar um WAITFOR (RECEIVE) e executar o DBCC OPENTRAN, ele mostrará a transação como ativa, mesmo na ausência de atualizações anteriores.
@binki esse comentário se refere ao SQL Server 2005. Isso é para 2008 R2. Eles se comportam de maneira diferente em relação a esse problema, se bem me lembro.
WAITFOR (...) TIMEOUT 3600000
resolver o problema? Por exemplo, liberar a cada hora.WAITFOR (RECEIVE...
Você poderia expandir? Talvez eu tenha entendido errado.begin transaction; waitfor(receive...)
não gerará nenhum registro de log (não 'ativará' a transação) enquanto aguarda e, portanto, não fixará o log. Somentebegin transaction;[insert|update|delete];waitfor(receive...)
fará com que a transação seja 'ativada' (gerar registros de log) e, portanto, realmente fixará o log enquanto aguarda.No SQL Server 2008 R2, se eu executar um WAITFOR (RECEIVE) e executar o DBCC OPENTRAN, ele mostrará a transação como ativa, mesmo na ausência de atualizações anteriores.
fonte