[Oracle Xe] - Qual a melhor maneira de detectar deadlock?

Oi,

Acho que o título deste post já diz tudo.

Como vocês (gujianos) fazem para identificar possíveis deads na base de dados? Alguém poderia me ajudar a “debulhar” o trace do Oracle?

Tchauzin!

[quote=lina]Oi,

Acho que o título deste post já diz tudo.

Como vocês (gujianos) fazem para identificar possíveis deads na base de dados? Alguém poderia me ajudar a “debulhar” o trace do Oracle?

Tchauzin![/quote]

oi,

http://www.dba-oracle.com/t_deadlock.htm

Oi,

Sim. Estou seguindo as seguintes regras para identificar os deads:

  • Locate the error messages in the alert log.
  • Locate the relevant trace file(s).
  • Identify the SQL statements in both the current session and the waiting session(s).
  • Use these SQL statements to identify the particular piece of code that is having problems.
  • Alter the appliation code to prevent deadlocks by always locking rows in the tables in the same order.

O problema é que está parecendo que o comando SQL do arquivo de trace não é exatamente o motivo do deadlock.

Tchauzin!

Oi,

Por exemplo, quando deu deadlock na aplicação, apresentou:

*** 2010-10-09 06:01:26.609 *** SERVICE NAME:(SYS$USERS) 2010-10-09 06:01:26.609 *** SESSION ID:(74.2) 2010-10-09 06:01:26.609 DEADLOCK DETECTED [Transaction Deadlock] Current SQL statement for this session: update .......

Então eu tenho esse UPDATE corrente.

Agora tem o seguinte gráfico:

The following deadlock is not an ORACLE error. It is a deadlock due to user error in the design of an application or from issuing incorrect ad-hoc SQL. The following information may aid in determining the deadlock: Deadlock graph: ---------Blocker(s)-------- ---------Waiter(s)--------- Resource Name process session holds waits process session holds waits TX-00110004-000022d1 41 74 X 40 75 X TX-000e0010-00002331 40 75 X 41 74 X session 74: DID 0001-0029-00000002 session 75: DID 0001-0028-00000002 session 75: DID 0001-0028-00000002 session 74: DID 0001-0029-00000002 Rows waited on: Session 75: obj - rowid = 0002BE81 - AAAr6BAAFAAAF0aAAf (dictionary objn - 179841, file - 5, block - 23834, slot - 31) Session 74: obj - rowid = 0002BE8B - AAAr6LAAFAAAJ2zAAA (dictionary objn - 179851, file - 5, block - 40371, slot - 0) Information on the OTHER waiting sessions: Session 75: pid=40 serial=2 audsid=23330 user: 293

Eu tenho 41 processos bloqueados e 40 esperando?

Logo abaixo da Session 75 eu tenho:

Current SQL Statement: update..... commad

Porém isso não quer dizer que foi este ultimo update que necessitou de recursos e acabou sendo bloqueado.

Já estou achando que a melhor saída seria colocar AutoCommit em tudo rsrs

O Grande problema é que depois de 1 deadlock, o sistema quase morre!

Tchauzin!

oi,

como você está criando (e destruindo) suas conexões com o banco? uma outra idéia é você fazer um dump da jvm, isso pode ajudar tb já que parece que o problema não é com o oracle e sim com a aplicação

[]´s

O engraçado é que o oracle já avisa que não é problema dele né… rsrs

Seguinte lina,

Precisa identificar todos os recursos que são compartilhados e estão sendo acessados, assim como os métodos que acessam esses recursos.
Isso pode ser feito imprimindo um texto no fechamento e abertura dos semáforos.

Pelo menos para mim é a maneira mais prática.

40 executando e 41 esperando,
sugiro um refactoring bem grande para diminuir o tamanho das transações, isto vai melhorar a performance e diminuir a probabilidade de ocorrerem deadlocks …

Boa pergunta.E lina, vc tá fechando as conexões dentro de um finally,certo?

Boa pergunta.E lina, vc tá fechando as conexões dentro de um finally,certo? [/quote]

Oi,

Claro! Fecho as conexões no finally!

Depois de olhar com calma o trace do Oracle, fui encontrar os 2 “supostos” comandos no programa.
Ambos estão seguidamente dentro de um Método e utilizando o mesmo sequencial no where. Algo do tipo:

[code]void Finalizar(DatabaseConnection ao_db) {

// Primeiro update
ao_db.Update TABELA_1 … where sequencial = 123456;

// Logo em seguida:
ao_db.Update TABELA_2 … where sequencial = 123456;

}[/code]

São tabelas diferentes. Porém, são FK.

Na primeira impressão, parece ser um deadlock (CDP) classico. Mais notem que ambas utilizam a mesma conexão e o update é feito em diferentes tabelas.

O que parece estranho é que no trace Oracle, aparece como sendo 2 conexões diferentes. Quem sabe uma thread possa ter alterado ou criado uma nova conexão… vai saber!

Como é triste fazer uma busca no código que não é seu! rs

Tchauzin!

[quote=urubatan]40 executando e 41 esperando,
sugiro um refactoring bem grande para diminuir o tamanho das transações, isto vai melhorar a performance e diminuir a probabilidade de ocorrerem deadlocks …
[/quote]

Oi,

O grande problema é que o sistema já está em produção e este dead ocorreu em 5 dias seguidos na semana passada!

Vou tentar colocar alguns Syserr para identificar o problema! (conforme sugerido pelo juliocbq)

Tchauzin!

oi,

pq vc não tenta dar uma olhadinha no jconsole

[]´s

[quote=André Fonseca]oi,

pq vc não tenta dar uma olhadinha no jconsole

[]´s[/quote]

Oi,

Obrigado pela dica… Agora que vou ter tempo para analisar esses deads.

Tchauzin!