Preciso ser capaz de iterar todas as tabelas e emitir um TRUNCATE
comando, porém, não quero que o loop seja interrompido por bloqueio. Essencialmente, estou procurando a melhor maneira de determinar se um SCH-M
bloqueio pode ser obtido antes de emitir um comando truncado.
Microsoft SQL Server 2019 (RTM-CU26) - 15.0.4365.2 (X64) Standard Edition (64 bits) no Windows Server 2016 Datacenter 10.0
A melhor maneira de testar se um bloqueio pode ser adquirido é tentar adquiri-lo.
Use
LOCK_TIMEOUT
para desistir após esperar um tempo especificado ou imediatamente se um bloqueio conflitante for encontrado, como preferir. UseTRY...CATCH
para lidar com qualquer erro e tente novamente mais tarde.Usar os bloqueios DMV não é confiável, pois é uma visão não transacional das estruturas internas de bloqueio. Um bloqueio conflitante pode aparecer facilmente por trás da sua digitalização. De qualquer forma, há um atraso entre a conclusão do teste e a tentativa de aquisição
Sch-M
.É melhor evitar a varredura das fechaduras do DMV tanto quanto possível para evitar interferir no que muitas vezes já é uma instalação interna altamente disputada.
Em teoria, você poderia verificar
sys.dm_tran_locks
se existe um bloqueio existente e, caso contrário, esperar e fazer um loop novamente.Mas, como observado por outros, isso pode não ser confiável, pois não é garantido que alguém não irá impedi-lo entre a verificação e o truncamento. Também coloca pressão extra no gerenciador de bloqueio.
Se você tiver uma tabela idêntica a esta, poderá usar
ALTER TABLE SWITCH
aWAIT_AT_LOW_PRIORITY
opção de alternar rapidamente a tabela para outra e truncá- la . Observe que esta opção não requer o loop acima.Supondo que isso esteja relacionado à sua pergunta anterior em uma tabela particionada, você pode fazer