Em primeiro lugar,
select
nunca bloqueia nada no Oracle, apenas usa a última versão consistente de dados disponível. Não é um caso para select ... for update
que bloqueia dados como update
desde o Oracle 9i, mas não há for update
cláusula na consulta da pergunta. Resource Name process session holds waits process session holds waits
TM-000151a2-00000000 210 72 SX SSX 208 24 SX SSX
A sessão #72 mantém o bloqueio de nível de tabela (TM) com o tipo "Row Exclusive" (SX) e deseja adquirir o bloqueio "Share Row Exclusive" (SSX) na mesma tabela. Esta sessão foi bloqueada pela Sessão #24, que já mantém o bloqueio em nível de tabela do mesmo tipo (SX) e aguarda enquanto o bloqueio SSX estaria disponível.
Resource Name process session holds waits process session holds waits
TM-000151a2-00000000 208 24 SX SSX 210 72 SX SSX
Esta (segunda linha) demonstra exatamente a mesma situação, mas na direção oposta:a Sessão #24 espera que o bloqueio SSX fique disponível, mas bloqueado pela Sessão #72 que já mantém o bloqueio SX na mesma tabela.
Assim, as Sessões #24 e Sessão #72 bloqueiam uma à outra:o deadlock acontece.
Ambos os tipos de bloqueio (SX e SSX) são bloqueios em nível de tabela.
Para entender a situação, recomendo ler este artigo de Franck Pachot.
Abaixo está a citação deste artigo, diretamente relevante para sua situação (observe que as abreviações SSX e SRX são equivalentes):
A integridade referencial também adquire bloqueios de TM. Por exemplo, o problema comum com chaves estrangeiras não indexadas leva a bloqueios S na tabela filho quando você emite uma exclusão ou atualização na chave na tabela pai. Isso ocorre porque, sem um índice, o Oracle não tem um único recurso de nível inferior para bloquear a fim de evitar uma inserção simultânea que possa violar a integridade referencial.
Quando as colunas de chave estrangeira são as colunas iniciais em um índice regular, a primeira entrada de índice com o valor-pai pode ser usado como um único recurso e bloqueado com um TXlock de nível de linha.
E se a integridade referencial tiver uma cascata de exclusão? Além do modo S, há a intenção de atualizar as linhas da tabela filha, como no modo Linha X (RX). É aqui que ocorre o share rowexclusive (SRX):S+RX=SRX.
Portanto, a variante mais provável é que a Sessão #72 e a Sessão #24 excluem algumas linhas em
EMPLOYEE
table ao mesmo tempo, e há on delete cascade
restrição para EMPSAL_EMP_ID
em conjunto com a ausência de índice em EMPLOYEE_SALARY
tabela na qual EMPSAL_EMP_ID
coluna listada primeiro.