miércoles, 5 de septiembre de 2007

Deadlocks --> ORA-00060

Qué es un Deadlock? Un Deadlock (abrazo mortal) es cuando 2 o más usuarios están esperando algún dato que está siendo loqueado por alguna sesión. Si ésto sucede, los usuarios involucrados en el Deadlock deben esperar y no pueden continuar con el procesamiento.

Cuando Oracle detecta que se produjo un Deadlock, lo que hace es cortar la ejecución del procedimiento y mostrar el siguiente mensaje de error: ORA-00060: deadlock detected while waiting for resource. Tengamos en cuenta que cuando se produce éste error, Oracle genera un archivo de trace en el directorio UDUMP con información acerca del error.

Generalmente éste problema se produce por un mal diseño de la aplicación. Veamos un ejemplo...

SQL_9iR2> CREATE TABLE sesion_1 AS
2 SELECT level id, 'nom_'||level nombre
3 FROM dual
4 CONNECT BY level <= 10 ;

Table created.

SQL_9iR2> CREATE TABLE sesion_2 AS
2 SELECT level id, 'nom_'||level nombre
3 FROM dual
4 CONNECT BY level <= 10 ;

Table created.

En la SESION 1 loqueo un registro de la tabla SESION_1 correspondiente al ID 1.

SQL_9iR2> UPDATE sesion_1
2 SET nombre = 'nom_'||id*2
3 WHERE id = 1 ;

1 row updated.

En la SESION 2 loqueo un registro de la tabla SESION_2 correspondiente al ID 1.

SQL_9iR2> UPDATE sesion_2
2 SET id = id+10
3 WHERE id = 1 ;

1 row updated.

En la SESION 1 modifico un registro de la tabla SESION_2 correspondiente al ID 1. Vemos que esta sesión se 'colgó' debido al loqueo y no nos devuelve el control. Todavía no se produjo el Deadlock... sólo se produjo un loqueo.

SQL_9iR2> UPDATE sesion_2
2 SET id = id+10
3 WHERE id = 1 ;

En la SESION 2 modifico un registro de la tabla SESION_1 correspondiente al ID 1.
Vemos que esta sesión se 'colgó' debido al loqueo y no nos devuelve el control.

SQL_9iR2> UPDATE sesion_1
2 SET nombre = 'nom_'||id*2
3 WHERE id = 1 ;

Esto va a producir un Deadlock y luego de unos segundos aparece un mensaje de error en la SESION 1:

SQL_9iR2> UPDATE sesion_2
2 SET id = id+10
3 WHERE id = 1 ;
UPDATE sesion_2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

La SESION 2 sigue colgada esperando que la SESION 1 termine la transacción que comenzó. Entonces en la SESION 1 ejecutamos...

SQL_9iR2> rollback ;

Rollback complete.

En la SESION 2 se libera automáticamente el loqueo...

SQL_9iR2> UPDATE sesion_1
2 SET nombre = 'nom_'||id*2
3 WHERE id = 1 ;

1 row updated.

3 comentarios:

Lorena dijo...

Este articulo fue de muchisima ayuda en mi trabajo,
soy responsable de soporte para un aplicacion multinacion de recursos humanos y nos encontramos muchas veces con este tipo de errores de oracle,
Esto nos oriento a buscar mas alla y poder pedir la mejora en la aplicacion para disminir estos problemas.

Irma dijo...

Buen dia, me sucede el DeadLock en mi aplicacion pero no he podido eliminarlo, como puedo saber que procesos lo generan?
De antemano Gracias

Leonardo Horikian dijo...

Hola Irma,

Cada vez que ocurre un deadlock, se genera un archivo de trace en el servidor donde se encuentra instalada la base de datos. Ese archivo de trace tiene información útil que te va a ayudar a entender dónde se está produciendo el deadlock.

Para saber dónde se genera el archivo de trace, ejecuta la siguiente consulta:

select value from v$parameter where name='user_dump_dest';

Saludos