Mastering ORA-00054: Resolving the "Resource Busy" Error
The ORA-00054 error, often accompanied by the message "resource busy and acquire with NOWAIT specified," is a common hurdle for Oracle database professionals. This error signals a contention problem, where a session is attempting to lock a resource (like a row or a table) that is already locked by another session, and it's doing so with an instruction to not wait. This guide will provide a comprehensive understanding of why this error occurs, how to diagnose the blocking session, and the most effective strategies for resolution and prevention.
The Foundation: Locking and Concurrency
To understand ORA-00054, you must first grasp Oracle's locking mechanisms. Oracle uses locks to manage data concurrency and integrity. When a session modifies data (e.g., with UPDATE, INSERT, DELETE, or SELECT ... FOR UPDATE), it places a lock on the affected rows. This prevents other sessions from modifying the same data until the first session either COMMITs or ROLLBACKs the transaction.
By default, when a session attempts to acquire a lock on a resource that is already locked, it will wait until the blocking session releases the lock. This is a "WAIT" mode.
The ORA-00054 error occurs when a session explicitly uses a NOWAIT clause. This clause tells Oracle not to wait for the lock to become available. If the lock cannot be acquired immediately, the transaction is terminated, and the ORA-00054 error is raised.
The Breakdown: Why the Resource Is Busy
The "resource busy" part of the error message is the key. The resource can be one of several things:
Row-Level Lock: The most frequent cause. Another session is in the middle of a transaction (e.g., an
UPDATE) on a specific row that your session is trying to modify.Table-Level Lock: A less common but more severe form of locking. This can happen when a session is performing a DDL (Data Definition Language) operation, such as
ALTER TABLE, or when it's using aLOCK TABLEcommand.Partition-Level Lock: Similar to a table lock, but restricted to a specific partition of a table. This often occurs during partition maintenance operations.
Deadlock-related Lock: While
ORA-00060is the specific error for deadlocks, a session in a deadlock situation can hold a lock that causes another session withNOWAITto fail withORA-00054.
Diagnosis: Pinpointing the Blocking Session
The key to resolving ORA-00054 is to identify which session is holding the lock. This is where your diagnostic skills come into play.
Query
V$LOCKandV$SESSION: These two views are your primary tools. You can join them to find theSID(Session ID) andSERIAL#of the blocking session.
SELECT
s.sid,
s.serial#,
s.username,
s.program,
s.machine,
s.logon_time,
s.sql_id,
'IS BLOCKING ->' as is_blocking,
l.id1, l.id2, l.lmode, l.request
FROM
v$lock l,
v$session s
WHERE
l.id1 IN (
SELECT id1 FROM v$lock WHERE request > 0
)
AND l.lmode > 0
AND l.sid = s.sid;
-- The blocking session is the one with request = 0 and lmode > 0.
-- The blocked session is the one with request > 0.
Use
DBA_BLOCKERSandDBA_WAITS: These views provide a more direct way to identify blockers and the sessions they are holding up.
SELECT
w.waiting_session AS waiting_sid,
h.holding_session AS blocking_sid,
h.lock_type,
h.mode_held,
w.mode_requested
FROM
dba_blockers h,
dba_waits w
WHERE
h.holding_session = w.holding_session
AND h.waiting_session != h.holding_session;
Check the
SQL_ID: Once you have the blockingSID, you can look up itsSQL_IDinV$SESSIONto see what query it is running. You can then useV$SQLto get the full SQL text.
SELECT sql_text FROM v$sql WHERE sql_id = 'your_blocking_sql_id';
Resolution: A Practical Guide
Once you've identified the cause, you can apply the appropriate solution. The goal is to release the lock, but the method depends on the situation.
1. Commit or Rollback the Blocking Session
If the blocking session is a short-lived transaction (e.g., an ad-hoc query from a developer), the simplest solution is to ask the user to COMMIT or ROLLBACK their changes. If the session is an application process, you might need to investigate why the transaction is running so long.
2. Terminate the Blocking Session
If the blocking session is an inactive, long-running transaction from a defunct application or a forgotten ad-hoc query, you may need to terminate it.
ALTER SYSTEM KILL SESSION 'sid, serial#';
Warning: Only do this if you are certain the session is not critical. Killing a session will cause its transaction to roll back, potentially losing work.
3. Redesign the Application Logic
The ORA-00054 error is a strong indicator of a flawed application design, specifically with its use of the NOWAIT clause.
Remove
NOWAIT: The most direct solution is to remove theNOWAITclause from the application code. This will cause the session to wait for the lock instead of failing immediately.Implement a Retry Mechanism: If
NOWAITis a hard requirement, the application should be designed to handle the error gracefully. It should catch theORA-00054exception and implement a retry loop with a short delay (e.g.,dbms_lock.sleep(1)) to re-attempt the lock acquisition. This gives the blocking session time to finish.Optimize Transactions: Reduce the duration of transactions to minimize the time locks are held. Commit changes more frequently if possible, or perform updates in smaller batches.
4. Avoid Table-Level Locks
Be cautious with DDL operations on tables during peak hours. If a table-level lock is required, schedule the operation for a maintenance window.
Video Resources
Oracle Lock Tuning and Deadlock Detection
Understanding Oracle Session Locks
Conclusion
The ORA-00054 error is a consequence of poor concurrency management, often exacerbated by an application's use of the NOWAIT clause. By using Oracle's dynamic performance views (V$LOCK, V$SESSION) to diagnose the root cause, you can effectively resolve the issue by either terminating the blocking session or, more importantly, by redesigning the application to handle lock contention gracefully. A well-designed application should either wait for locks to be released or implement a robust retry mechanism, turning a potential error into a smoothly handled delay.
No comments:
Post a Comment