Este pequeño post lo agrego para Milton (Ecuador) que me preguntaba como podia armar un script para consultar sessiones que estuvieran con bloqueos esperando a que otro usaruario termine la operación.
Lo que le había occurido, en una prueba de Java con Oracle, es que la aplicación se hangeo y para poder ejecutar la prueba desde la contingencia de su aplicación debía primero truncar la tabla.
Al intentar hacerlo le daba el error:
SQL> truncate table TEST.VOL_MONEY_CAP ; truncate table TEST.VOL_MONEY_CAP * ERROR at line 1: ORA-00054: resource busy and acquire with NOWAIT specified
Este error ocurre cuando se bloquea un/unos registro/s mediante:
- Las sentencias SQL «SELECT» especificados como «NO WAIT» o «FOR UPDATE NOWAIT».
- Que una operación SQL de tipo DDL fue blockeada.
Una solución podría ser haciendo COMMIT o ROLLBACK en la sesión de bloqueo.
Entendamos un poco lo que estamos haciendo.
Yo utilizo para la query que se demuestra al pie la vista v$lock.
De acá podemos decir que los tipos de lockeos son:
- TM – DML enqueue
- TX – Transaction enqueue
- UL – User supplied
Para encontrar que proceso esta blokeados usamos la query.
SQL> select * from v$lock where request!=0;
Y como el blockeo se produce cuando quiero realizar un truncate, lo que hago es revisar en la tabla dba_dml_locks.
SQL> select mode_held from dba_dml_locks where owner=’TEST’; MODE_HELD ————- Row-X (SX) Row-X (SX) Row-X (SX)
Ahora puedo listar los blockeos que ocurren en este momento en mi base de datos.
Y podemos observar por medio de los campos LMODE y REQUEST de que tipo es :
- none
- null (NULL)
- row-S (SS)
- row-X (SX)
- share (S)
- S/Row-X (SSX)
- exclusive (X)
Ejecutemos la prueba.
SQL> set linesize 130 set pages 100 col username format a20 col sess_id format a10 col object format a25 col mode_held format a10 select oracle_username || ‘ (‘ || s.osuser || ‘)’ username , s.sid || ‘,’ || s.serial# sess_id , owner || ‘.’ || object_name object , object_type , decode( l.block , 0, ‘Not Blocking’ , 1, ‘Blocking’ , 2, ‘Global’) status , decode(v.locked_mode , 0, ‘None’ , 1, ‘Null’ , 2, ‘Row-S (SS)’ , 3, ‘Row-X (SX)’ , 4, ‘Share’ , 5, ‘S/Row-X (SSX)’ , 6, ‘Exclusive’, TO_CHAR(lmode)) mode_held from v$locked_object v , dba_objects d , v$lock l , v$session s where v.object_id = d.object_id and v.object_id = l.id1 and v.session_id = s.sid order by oracle_username , session_id /SQL> SQL> SQL> SQL> SQL> SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 USERNAME SESS_ID OBJECT OBJECT_TYPE STATUS MODE_HELD ——————– ——————— ————————————————————————————— ————————————————— ———— ————————— AP (jcaps) 48,367 TEST.VOL_MONEY_CAP TABLE Not Blocking Row-X (SX) AP (jcaps) 48,367 TEST.VOL_MONEY_CAP TABLE Not Blocking Row-X (SX) AP (jcaps) 145,123 TEST.VOL_MONEY_CAP_HISTORICA TABLE Not Blocking Row-X (SX) AP (jcaps) 160,339 TEST.VOL_MONEY_CAP TABLE Not Blocking Row-X (SX) AP (jcaps) 160,339 TEST.VOL_MONEY_CAP TABLE Not Blocking Row-X (SX) SQL>
Ahora que sabemos que ocurrio y desde que cliente se estan conectando podemos tomar las medidas adecuadas del caso.
Hola, se peude realizar un «desbloqueo» de la tabla si no tengo privilegios de dba
Me gustaMe gusta