Ao executar sob READ COMMITTED
(o tipo pessimista, não RCSI), acabei de ver um UPDATE
deadlock de bloqueio IX de 's com um SELECT
bloqueio compartilhado de 's no PAGE
nível -. Eles SELECT
executaram com um plano de execução paralelo. Nenhum deles usou explicitamente uma transação. Entendo que UPDATE
s implicitamente criam transações. Isso sugere que SELECT
s paralelos também criam transações implícitas? Isso não é verdade para s não paralelos SELECT
?
Estou achando isso um tanto confuso, porque nenhum dos exemplos de deadlocks nos livros didáticos mostra duas consultas sem transação gerando deadlocks.
não é a transação
Se você jogar Lock Compatibility Battleship ™️, verá que os Shared Locks não podem afundar seu destroyer facilmente, mas os Object-Level Shared Locks são um tipo diferente de torpedo. Você nem terá tempo para um ping apenas.
Na maioria dos casos, os bloqueios S são tomados e liberados muito rapidamente, mas há certas coisas que prolongarão esses bloqueios. Eu bloguei sobre eles em relação a Key Lookups com Prefetching:
A primeira coisa que eu olharia é o plano de consulta para a consulta de seleção paralela e veria se há alguma pesquisa com o atributo prefetch. Em alguns casos, consertar a pesquisa com colunas de índice adicionais é fácil o suficiente. Em outros casos, você pode precisar sugerir um índice diferente.
Se a pesquisa foi escolhida com base em estimativas de cardinalidade ruins ou por causa da detecção de parâmetros, você pode decidir por um caminho diferente para resolver o problema.
Caso esse não seja o caso, forneça os planos de consulta para a seleção e para a consulta de modificação, juntamente com qualquer informação contextual útil, como definições de tabela e índice, gatilhos, visualizações indexadas, etc.
Sim, o
SELECT
será executado em uma transação (e criará uma se necessário, pois ou você está executando no modo de confirmação automática ou está executando com transações implícitas ativadas eSELECT
não é a exceção mencionada aqui ). Isso se aplica igualmente a planos de execução serial ou paralela.Se você começar a partir
SELECT
de uma tabela grande no modo de confirmação automática em uma janela e for para outra e executarenquanto o original
SELECT
ainda estiver em execução, você verá que o(s) bloqueio(s) mantido(s) peloSELECT
são alocados para uma transação e se você repetir o experimento e adicionarCURRENT_TRANSACTION_ID()
àSELECT
lista na tabela grande, verá que o valor retornado por corresponde aorequest_owner_id
retornado pelasys.dm_tran_locks
consulta.Essas
SELECT
transações de confirmação automática não parecem aparecersys.dm_tran_session_transactions
, como mostrado abaixo (ondedm_tran_current_transaction
felizmente relata detalhes de uma transação não mostrada no outro DMV).Eles também não disparam nenhum evento estendido relacionado a transações, até onde pude ver, então eles parecem uma variante muito leve do tema.