CREATE TABLE table1 (id NUMBER, value VARCHAR2(50)); CREATE TABLE table2 (id NUMBER, value VARCHAR2(50)); INSERT INTO table1 VALUES (1, 'DBDOCS A'); INSERT INTO table2 VALUES (1, 'DBDOCS B'); COMMIT;
-- Lock a row in table1 UPDATE table1 SET value = 'X' WHERE id = 1;
-- Lock a row in table2 UPDATE table2 SET value = 'Y' WHERE id = 1;
-- Try to lock a row in table2 (will wait for Session 2 to release the lock) UPDATE table2 SET value = 'Z' WHERE id = 1;
-- Try to lock a row in table1 (will wait for Session 1 to release the lock) UPDATE table1 SET value = 'W' WHERE id = 1;
# Check the alert log for deadlock information tail -f $ORACLE_BASE/diag/rdbms/$ORACLE_SID/$ORACLE_SID/trace/alert_$ORACLE_SID.log 2024-06-01T10:04:52.972510-04:00 DBDOCSPDB(3):Errors in file /opt/oracle/diag/rdbms/dbdocs/dbdocs/trace/dbdocs_ora_3602.trc: 2024-06-01T10:04:53.215029-04:00 DBDOCSPDB(3):ORA-00060: Deadlock detected. See Note 60.1 at My Oracle Support for Troubleshooting ORA-60 Errors. More info in file /opt/oracle/diag/rdbms/dbdocs/dbdocs/trace/dbdocs_ora_3602.trc.
# Locate and view the trace file cd $ORACLE_BASE/diag/rdbms/$ORACLE_SID/$ORACLE_SID/trace ls -ltr *.trc cat
2024-06-01 10:04:52.900*:ksq.c@13216:ksqdld_hdr_dump(): DEADLOCK DETECTED ( ORA-00060 ) See Note 60.1 at My Oracle Support for Troubleshooting ORA-60 Errors [Transaction Deadlock] 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 serial process session holds waits serial TX-00010006-0000027B-679AC9F0-00000000 54 9 X 27628 86 272 X 55042 TX-00090017-00000257-679AC9F0-00000000 86 272 X 55042 54 9 X 27628 ----- Information for waiting sessions ----- Session 9: sid: 9 ser: 27628 audsid: 60016 user: 109/DBDOCS_USER pdb: 3/DBDOCSPDB flags: (0x41) USR/- flags2: (0x40009) -/-/INC flags_idl: (0x1) status: BSY/-/-/- kill: -/-/-/-/- pid: 54 O/S info: user: oracle, term: UNKNOWN, ospid: 3602 image: oracle@dbdocs client details: O/S info: user: oracle, term: pts/0, ospid: 3600 machine: dbdocs program: sqlplus@dbdocs (TNS V1-V3) application name: SQL*Plus, hash value=3669949024 current SQL: UPDATE table2 SET value = 'Z' WHERE id = 1 Session 272: sid: 272 ser: 55042 audsid: 60021 user: 109/DBDOCS_USER pdb: 3/DBDOCSPDB flags: (0x41) USR/- flags2: (0x40009) -/-/INC flags_idl: (0x1) status: BSY/-/-/- kill: -/-/-/-/- pid: 86 O/S info: user: oracle, term: UNKNOWN, ospid: 3820 image: oracle@dbdocs client details: O/S info: user: oracle, term: pts/1, ospid: 3818 machine: dbdocs program: sqlplus@dbdocs (TNS V1-V3) application name: SQL*Plus, hash value=3669949024 current SQL: UPDATE table1 SET value = 'W' WHERE id = 1 ----- End of information for waiting sessions -----
select -- Session causing the block blockers.blocker_instance_id as blocker_instance_id, blocker.sid as blocker_sid, blocker.serial# as blocker_serial#, blocker.username as blocker_username, blocker.status as blocker_status, blocker.machine as blocker_machine, blocker.program as blocker_program, blocker.sql_id as blocker_sql_id, blocker.sql_child_number as blocker_sql_child_number, blocker.prev_sql_id as blocker_prev_sql_id, blocker.prev_child_number as blocker_prev_child_number, '->' as is_blocking, -- Sesssion being blocked blocked.sid as blocked_sid, blocked.serial# as blocked_serial#, blocked.username as blocked_username, blocked.status as blocked_status, blocked.machine as blocked_machine, blocked.program as blocked_program, blocked.blocking_session as blocked_blocking_session, blocked.sql_id as blocked_sql_id, blocked.sql_child_number as blocked_sql_child_number, sys_obj.name as blocked_table_name, dbms_rowid.rowid_create( rowid_type => 1, object_number => blocked.row_wait_obj#, relative_fno => blocked.row_wait_file#, block_number => blocked.row_wait_block#, row_number => blocked.row_wait_row# ) as blocked_rowid, blockers.wait_id as blocked_wait_id, blockers.wait_event as blocked_wait_event, blockers.wait_event_text as blocked_wait_event_text, blockers.con_id as data_container_id, -- Blocker * Blocked SQL Text blocker_sql.sql_text as blocker_sql_text, blocker_prev_sql.sql_text as blocker_prev_sql_text, blocked_sql.sql_text as blocked_sql_text from v$session_blockers blockers inner join v$session blocker on blocker.sid = blockers.blocker_sid and blocker.serial# = blockers.blocker_sess_serial# inner join v$session blocked on blocked.sid = blockers.sid and blocked.serial# = blockers.sess_serial# inner join sys.obj$ sys_obj on sys_obj.obj# = blocked.row_wait_obj# left outer join v$sql blocked_sql on blocked_sql.sql_id = blocked.sql_id and blocked_sql.child_number = blocked.sql_child_number left outer join v$sql blocker_sql on blocker_sql.sql_id = blocker.sql_id and blocker_sql.child_number = blocker.sql_child_number left outer join v$sql blocker_prev_sql on blocker_prev_sql.sql_id = blocker.prev_sql_id and blocker_prev_sql.child_number = blocker.prev_child_number where blocked.status = 'ACTIVE';
Instance ID, SID, serial number, username, status, machine, program
SQL IDs
SID, serial number, username, status, machine, program, blocking session, current SQL ID and child number, blocked table name, row ID being blocked, wait ID, wait event
wait event text
SELECT FOR UPDATE
SET TRANSACTION
INITRANS
MAXTRANS
-- Begin transaction -- Lock a row in table1 UPDATE table1 SET value = 'X' WHERE id = 1; -- Lock a row in table2 UPDATE table2 SET value = 'Z' WHERE id = 1; COMMIT;
-- Begin transaction -- Lock a row in table1 (acquire locks in the same order as Session 1) UPDATE table1 SET value = 'W' WHERE id = 1; -- Lock a row in table2 UPDATE table2 SET value = 'Y' WHERE id = 1; COMMIT;
--SYNTAX : alter system kill session 'SID,SERIAL#' immediate; SQL> alter system kill session '9,27628' immediate; System altered. SQL>