Está en la página 1de 10

ORACLE Interbloqueos

Un interbloqueo se produce cuando dos o ms sesiones a la espera de los datos bloqueados por la otra, dando lugar a todas las sesiones estn bloqueadas. Oracle automticamente detecta y resuelve los bloqueos por revertir el estado asociado a la transaccin que detecta el punto muerto. Normalmente, los bloqueos son causados por bloqueo mal implementado en el cdigo de aplicacin. Este artculo muestra los pasos necesarios para identificar el cdigo de la aplicacin ofender cuando se detecta un interbloqueo. Crea un usuario de prueba. Creacin de test usuario identificado por prueba DEFAULT TABLESPACE usuarios TABLESPACE temp TEMPORAL QUOTA UNLIMITED los usuarios; GRANT CONNECT, CREATE TABLE para poner a prueba; GRANT EXECUTE ON DBMS_LOCK para poner a prueba;

Crear un esquema de prueba. CONN test / prueba CREATE TABLE deadlock_1 ( Nmero de identificacin ); CREATE TABLE deadlock_2 ( Nmero de identificacin ); INSERT INTO deadlock_1 (id) VALUES (1); INSERT INTO deadlock_2 (id) VALUES (1); COMMIT;

Inicie dos sesiones de SQL * Plus, cada uno conectado al usuario de prueba, a continuacin, ejecute las siguientes piezas de cdigo, uno en cada sesin. - Ejecutar en la sesin 1. DECLARAR TIPO l_deadlock_1_id% deadlock_1.id; TIPO l_deadlock_2_id% deadlock_2.id; COMENZAR - Bloquear las filas de la primera tabla.

SELECT id EN l_deadlock_1_id DE deadlock_1 WHERE id = 1 Para la actualizacin; - Pausa. DBMS_LOCK.sleep (30); - Bloquear las filas de la segunda tabla. SELECT id EN l_deadlock_2_id DE deadlock_2 WHERE id = 1 Para la actualizacin; - Libera bloqueos. ROLLBACK; END; / - Ejecutar en la sesin 2. DECLARAR TIPO l_deadlock_1_id% deadlock_1.id; TIPO l_deadlock_2_id% deadlock_2.id; COMENZAR - Bloquear las filas de la segunda tabla. SELECT id EN l_deadlock_2_id DE deadlock_2 WHERE id = 1 Para la actualizacin; - Pausa. DBMS_LOCK.sleep (30); - Bloquear las filas de la primera tabla. SELECT id EN l_deadlock_1_id DE deadlock_1 WHERE id = 1 Para la actualizacin; - Libera bloqueos. ROLLBACK; END; / La primera pieza de cdigo obtiene un bloqueo en una fila en la DEADLOCK_1 mesa, se detiene durante 30 segundos, a continuacin, intenta obtener un bloqueo en una fila en la DEADLOCK_2 mesa. La segunda pieza de cdigo hace lo mismo pero a la inversa, el bloqueo de una fila de la DEADLOCK_2 tabla, el DEADLOCK_1 mesa. La llamada a la DBMS_LOCK.SLEEP procedimiento slo est presente para darle tiempo suficiente para cambiar de sesiones.

Finalmente, una de las sesiones se detecta el punto muerto, deshacer su transaccin y producir un error callejn sin salida, mientras que la otra transaccin se completa satisfactoriamente. Un error tpico callejn sin salida se muestra a continuacin. ERROR en lnea 1: ORA-00060: deadlock detectado a la espera de los recursos ORA-06512: en lnea 16

Adems del error de interbloqueo a la sesin, un mensaje se coloca en el registro de alertas. ORA-00060: Deadlock detectado. Ms informacin en el archivo c: \ oracle \ product \ 10.2.0 \ admin \ db10g \ udump \ db10g_ora_4200.trc.

El mensaje de error contiene una referencia a un archivo de rastreo, cuyo contenido indican las instrucciones SQL bloqueados tanto en la sesin que ha detectado el punto muerto y las otras sesiones bloqueadas. 09/13/2006 09:11:40.646 *** *** NOMBRE DE ACCIN: () 13/09/2006 09:11:40.615 *** NOMBRE DEL MDULO: (SQL * Plus) 13/09/2006 09:11:40.615 *** NOMBRE DEL SERVICIO: (SYS $ Users) 13/09/2006 09:11:40.615 SESIN *** Identificacin: (137.7008) 13/09/2006 09:11:40.615 DEADLOCK DETECTADO [Deadlock transacciones] Instruccin SQL actual para esta sesin: SELECT ID DE DEADLOCK_2 WHERE ID = 1 FOR UPDATE ----- PL / SQL Call Stack ----objeto objeto de lnea manejar nombre nmero 16 1AFBE484 bloque annimo El punto muerto que sigue no es un error de ORACLE. Se trata de un punto muerto debido a un error del usuario en el diseo de una aplicacin o de la emisin incorrecta ad-hoc de SQL. Las siguientes informacin puede ayudar a determinar el punto muerto: Deadlock grfico: --------- Blocker (s) ----------------- Waiter (s) --------Nombre del recurso sesin proceso mantiene esperas sesin proceso tiene espera TX-0006001a 0000131b-19 137 X 24 159 X TX-00030028-00001313 24 159 X 19 137 X sesin 137: DID 0001-0013-000067B7 sesin 159: DID desde 0001 hasta 00180000100C sesin 159: DID 0.001-0018-0000100C sesin 137: 0001-0013 DID-000067B7 Filas esper en: Sesin 159: obj - ROWID = 0000E6C7 - AAAObHAAEAAAABAAAA (Diccionario objn - 59079, expediente - 4, bloque - 64, ranura - 0) Sesin 137: obj - ROWID = 0000E6C8 - AAAObIAAEAAAABIAAA (Diccionario objn - 59080, expediente - 4, bloque - 72, ranura - 0) La informacin sobre las sesiones en espera: Sesin 159: pid = 24 serial = 51383 = 43465 audsid usuario: 62/TEST

O / S info: usuario: tim_hall, duracin: winxp1, ospid: 5928:3844, mquina: winxp1 programa: sqlplusw.exe Nombre de la aplicacin: SQL * Plus, valor hash = 3669949024 Actual Estado SQL: SELECT ID DE DEADLOCK_1 WHERE ID = 1 FOR UPDATE Fin de la informacin sobre otras sesiones en espera. ========================================== =========

Las secciones en negrita son del mayor inters. En la primera seccin se muestra la instruccin SQL bloqueado en la sesin que ha detectado el punto muerto. La segunda seccin es un mensaje de Oracle diciendo que se trata de una cuestin de aplicacin, no un error de Oracle. En la tercera seccin se enumeran los estados bloqueados SQL en las otras sesiones en espera. Las sentencias de SQL que figuran en el archivo de seguimiento debera permitir identificar el cdigo de la aplicacin que est causando el problema. Para resolver el problema, asegrese de que las filas de las tablas siempre estn encerrados en el mismo orden. Por ejemplo, en el caso de una relacin maestro-detalle, usted puede decidir bloquear siempre una fila de la tabla maestra antes de bloquear una fila en la tabla de detalles. En resumen, las medidas necesarias para identificar y rectificar los bloqueos que causan el cdigo son: Localice los mensajes de error en el registro de alertas. Busque el archivo de rastreo correspondiente (s). Identificar las sentencias SQL, tanto en el actual perodo de sesiones y la sesin de espera (s). Utilice estas instrucciones SQL para identificar la parte del cdigo que est teniendo problemas. Alterar el cdigo de la aplicacin para evitar puntos muertos por bloqueo siempre filas de las tablas en el mismo orden.

Deteccin de Deadlock Oracle automticamente detecta situaciones de punto muerto y los resuelve revirtiendo una de las declaraciones que participan en el interbloqueo, liberando as un conjunto de los bloqueos de fila en conflicto. Un mensaje correspondiente tambin se devuelve a la transaccin que sufre de nivel de instruccin de reversin. La declaracin deshace es el que pertenece a la transaccin que detecta el punto muerto. Por lo general, la transaccin sealada debera deshacer explcitamente, pero se puede volver a intentar la declaracin enrollado de nuevo despus de esperar. Nota: En las transacciones distribuidas, estancamientos locales se detectan mediante el anlisis de los datos de espera, y estancamientos globales son detectados por un tiempo de espera. Una vez detectado, no distribuidas y interbloqueos distribuidos son manejados por la base de datos y aplicacin de la misma manera. Interbloqueos ocurren con mayor frecuencia cuando las transacciones explcitamente anular el bloqueo por defecto de Oracle. Debido a que Oracle s mismo no hace ninguna extensin de

bloqueo y no utiliza bloqueos de lectura para las consultas, pero no uso el bloqueo de filas (en lugar de bloqueo a nivel de pgina), bloqueos ocurren con poca frecuencia en Oracle.

MySQL
Interbloqueos
Los deadlocks son un problema clsico de las bases de datos transaccionales, pero no son peligrosos a menos que sean tan frecuentes que no se puedan ejecutar en absoluto ciertas transacciones. Normalmente, las aplicaciones deben ser escritas de modo que esten preparadas para emitir nuevamente una transaccin si sta es cancelada debido a un deadlock. InnoDB emplea bloqueos automticos a nivel de fila. Se pueden producir deadlocks an en el caso de transacciones que solamente insertan o eliminan una fila individual. Esto se debe a que estas operaciones no son realmente atmicas; sino que establecen automticamente bloqueos enlos (posiblemente varios) registros de ndice de la fila insertada o eliminada. Con las siguientes tcnicas se puede estar a cubierto de los deadlocks y reducir la probabilidad de que ocurran:

Emplear SHOW INNODB STATUS para determinar la causa del ltimo deadlock. Puede ayudar a afinar la aplicacin para evitar que ocurran otros. Siempre hay que estar preparado para emitir nuevamente una transaccin que haya fallado por un deadlock. Los deadlocks no revisten peligro, simplemente hay que intentar de nuevo. Confirmar las transacciones frecuentemente. Las transacciones pequeas son menos propensas a originar conflictos. Si se estn usando lecturas que establecen bloqueos (SELECT ... FOR UPDATE o ... LOCK IN SHARE MODE), hay que intentar utilizar un nivel de aislamiento bajo, como READ COMMITTED. Acceder a las tablas y filas en un orden fijo. Entonces, las transacciones forman secuencias bien definidas y no originan deadlocks. Agregar a las tablas ndices adecuadamente elegidos. Entonces las consultas necesitarn examinar menos registros de ndice y en consecuencia establecern menos bloqueos.

Utilizar EXPLAIN SELECT para determinar los ndices que MySQL considera ms apropiados para las consultas.

Utilizar menos el bloqueo. Si es aceptable que SELECT devuelva datos de una captura de la base de datos que no sea la ms actualizada, no hay que agregarle las clusulas FOR UPDATE o LOCK IN SHARE MODE. En este caso es adecuado utilizar el nivel de aislamiento READ COMMITTED, porque cada lectura consistente dentro de la misma transaccin leer de su propia captura ms reciente. Si nada de esto ayuda, habr que serializar las transacciones con bloqueos a nivel de tabla. La forma correcta de emplear LOCK TABLES con tablas transaccionales, como InnoDB, es establecer AUTOCOMMIT = 0 y no invocar aUNLOCK TABLES hasta que se haya confirmado explcitamente la transaccin. Por ejemplo, si se necesitara escribir en una tabla t1 y leer desde una tabla t2, se puede hacer esto: SET AUTOCOMMIT=0; LOCK TABLES t1 WRITE, t2 READ, ...; [aqu se hace algo con las tablas t1 y t2]; COMMIT;

UNLOCK TABLES; Los bloqueos a nivel de tabla favorecen el funcionamiento de la cola de transacciones, y evitan los deadlocks.

Otra manera de serializar transacciones es crear una tabla semforo auxiliar que contenga slo una fila. Hay que hacer que cada transaccin actualice esa fila antes de acceder otras tablas. De ese modo, todas las transacciones se producirn en serie. Ntese que el algoritmo de deteccin instantnea de deadlocks de InnoDBtambin funciona en este caso, porque el bloqueo de serializacin es un bloqueo a nivel de fila. Con los bloqueos a nivel de tabla de MySQL, debe emplearse el mtodo de timeout para solucionar deadlocks. En aquellas aplicaciones que emplean el comando de MySQL LOCK TABLES, MySQL no establece bloqueos de tabla si AUTOCOMMIT=1.

POSTGRE. Interbloqueos
El uso de bloqueos explcitos puede aumentar la probabilidad de bloqueo de puertas , en los que dos (o ms) las operaciones de Seguros de las bodegas que el otro quiere. Por ejemplo, si una transaccin adquiere un bloqueo exclusivo en la tabla A y luego intenta adquirir un bloqueo exclusivo en la tabla B, mientras que la transaccin 2 ya tiene exclusivo de bloqueo de la tabla B y ahora quiere un bloqueo exclusivo en la tabla A, entonces tampoco se puede proceder . PostgreSQL automticamente detecta situaciones de punto muerto y los resuelve abortando una de las transacciones involucradas, permitiendo que el otro (s) para completar. (Exactamente qu transaccin se aborta es difcil de predecir y no se debe confiar en ellas.) Tenga en cuenta que los interbloqueos tambin puede ocurrir como resultado de bloqueos a nivel de fila (y por tanto, pueden ocurrir incluso si el bloqueo explcito no se

utiliza).Consideremos el caso en el que dos transacciones simultneas modificar una tabla. La primera transaccin ejecuta:

Cuentas UPDATE SET saldo = saldo + 100.00 DONDE acctnum = 11111;

Esto adquiere un bloqueo a nivel de fila en la fila con el nmero de cuenta especificado. A continuacin, la segunda transaccin ejecuta:

Cuentas UPDATE SET saldo = saldo + 100.00 = DONDE acctnum 22222; Cuentas UPDATE SET saldo = saldo - 100,00 DONDE acctnum = 11111;

La primera

ACTUALIZACIN declaracin con xito adquiere un bloqueo a nivel de fila en la fila


por lo que tiene xito en la actualizacin de la fila. Sin embargo, la

especificada, segunda

ACTUALIZACIN instruccin halla que la fila que est intentando actualizar ya ha sido

bloqueado, por lo que espera a que la transaccin que ha adquirido el bloqueo para completar. Transaccin dos est ahora a la espera de una transaccin se complete antes de que contina la ejecucin. Ahora, ejecuta una transaccin:

Cuentas UPDATE SET saldo = saldo - 100,00 DONDE acctnum = 22222;

Transaccin se intenta adquirir un bloqueo a nivel de fila en la fila especificada, pero no puede: dos transacciones ya tiene una cerradura. Por lo tanto, espera transaccin de dos a completar. Por lo tanto, una transaccin est bloqueada en operacin dos, y dos transaccin est bloqueada en una transaccin:. Una condicin de interbloqueoPostgreSQL detectar esta situacin y abortar una de las transacciones. La mejor defensa contra bloqueos suele evitarlos por tener la certeza de que todas las aplicaciones que utilizan una base de datos adquiere bloqueos en varios objetos en un orden coherente. En el ejemplo anterior, si ambas transacciones hubieran actualizado las filas en el mismo orden, no se habra producido punto muerto. Tambin hay que asegurarse de que el primer bloqueo adquirido en un objeto en una transaccin es el modo ms restrictivo que sern necesarios para ese objeto. Si no es factible para verificar esto con antelacin, a continuacin, bloqueo de puertas puede ser manejado en la marcha por transacciones reintentando que debido a interbloqueos abortar. Siempre y cuando no se detecta la situacin de bloqueo, una transaccin que buscan ya sea a nivel de tabla o el bloqueo a nivel de fila esperar indefinidamente bloqueos en conflicto al ser puesto en libertad. Esto significa que es una mala idea para aplicaciones de celebrar transacciones abiertas durante largos perodos de tiempo (por ejemplo, a la espera de la entrada del usuario).

SQL SERVER
Deteccin de Deadlock
Todos los recursos mencionados en el apartado anterior participacin en el rgimen del motor de base de datos de deteccin de punto muerto. Deadlock deteccin se realiza mediante un subproceso de supervisin de bloqueo que, peridicamente, inicia una bsqueda a travs de todas las tareas en una instancia del motor de base de datos. Los puntos siguientes describen el proceso de bsqueda:

El intervalo predeterminado es de 5 segundos. Si el subproceso de supervisin de bloqueos encuentra interbloqueos, el intervalo de deteccin de punto muerto caer desde 5 segundos hasta un mnimo de 100 milisegundos, dependiendo de la frecuencia de puntos muertos.

Si el subproceso de supervisin de bloqueo stops interbloqueos constatacin, el motor de base aumenta los intervalos entre las bsquedas a 5 segundos. Si un interbloqueo se acaba de detectar, se supone que los hilos prximos que debe esperar un bloqueo estn entrando en el ciclo de interbloqueo. El primer par de bloqueo de espera despus de un estancamiento ha sido detectado inmediatamente dar lugar a una bsqueda de interbloqueos en lugar de esperar a que el intervalo de deteccin de estancamiento que viene. Por ejemplo, si el intervalo actual es de 5 segundos y un punto muerto se detect slo, la espera de bloqueo junto comenzar el detector de punto muerto inmediatamente. Si esta espera de bloqueo forma parte de un callejn sin salida, se detectar de inmediato en lugar de estancamiento durante la bsqueda siguiente.

El motor de base de datos por lo general realiza la deteccin de estancamiento peridico solamente. Debido a que el nmero de puntos muertos encontrados en el sistema es generalmente pequeo, deteccin de estancamiento peridica ayuda a reducir los gastos indirectos de deteccin de estancamiento en el sistema. Cuando el monitor de bloqueos inicia bsqueda de interbloqueos para un hilo en particular, identifica el recurso en el que el hilo est esperando. El monitor de bloqueo despus encuentra el propietario (s) de ese recurso en particular y de forma recursiva contina la bsqueda de interbloqueos para esos temas hasta que encuentra un ciclo.Un ciclo identificada de esta manera forma un punto muerto. Despus de un callejn sin salida es detectado, el motor de base de datos a un punto muerto termina eligiendo uno de los hilos como un sujeto del interbloqueo. El motor de base de datos termina el lote actual se est ejecutando para el hilo, retrotrae la transaccin de la vctima del interbloqueo y devuelve un error 1205 para la aplicacin.Anulacin de la transaccin para la vctima del interbloqueo libera todos los bloqueos mantenidos por la transaccin. Esto permite que las transacciones de los otros hilos a ser bloqueado y continuar. El 1205 interbloqueo registros error informacin sobre los temas y los recursos implicados en un interbloqueo en el registro de errores. Por defecto, el motor de base de datos elige como vctima del interbloqueo la sesin que ejecuta la transaccin que es menos costoso de revertir. Alternativamente, un usuario puede especificar la prioridad de las sesiones en una situacin de bloqueo se utiliza la instruccin DEADLOCK_PRIORITY SET. DEADLOCK_PRIORITY se puede ajustar a normal baja, o alto, o, alternativamente, se puede ajustar a cualquier valor entero en el rango de (-10 a 10). Los valores predeterminados de prioridad de interbloqueo en NORMAL. Si dos sesiones tienen distintas prioridades de interbloqueo, la sesin con la prioridad ms baja es elegida como sujeto del interbloqueo. Si ambas sesiones tienen la misma prioridad de interbloqueo, la sesin con la transaccin que es menos costoso de revertir que se elija. Si las sesiones que participan en el ciclo de interbloqueo tienen la misma prioridad de interbloqueo y el mismo costo, una vctima es elegida al azar.

Cuando se trabaja con CLR, el monitor de interbloqueo detecta automticamente estancamiento de los recursos de sincronizacin (monitores, lector / grabador de bloqueo de rosca y unirse) se accede dentro de los procedimientos administrados. Sin embargo, el punto muerto se resuelve lanzando una excepcin en el procedimiento que se ha seleccionado para ser el sujeto del interbloqueo. Es importante entender que la excepcin no se libera automticamente los recursos actualmente propiedad de la vctima, los recursos deben ser explcitamente puestos en libertad. De acuerdo con el comportamiento de excepcin, la excepcin utilizada para identificar un interbloqueo puede ser capturada y despedida.

Sitios consultados:
http://msdn.microsoft.com/en-us/library/ms178104(v=sql.105).aspx http://www.postgresql.org/docs/9.1/static/explicit-locking.html http://www.oracle-base.com/articles/misc/deadlocks.php http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html