Skip to content
Oracle Database

Oracle Error ORA-00054

resource busy (failed to acquire a lock held by another session)

Applies to: Oracle Database 19c, 21c, 23ai and 26ai (wording differs: see below)
Last technically reviewed 24 October 2026 on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally
The full message
ORA-00054: Failed to acquire a lock (Type: "TM", Name: "DML", Description: "Synchronizes accesses to an object") because it is currently held by another session. The resource being locked can be identified by 74855 ("Table") and 0 ("operation")
Other forms of this message
Oracle Database 19c and 21c
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
SQL*Plus and SQLcl show the statement and the failing line first
DROP TABLE my_transactions
*
ERROR at line 1:
ORA-00054: Failed to acquire a lock (Type: "TM", Name: "DML", Description: "Synchronizes accesses to an object") because it is currently held by another session. The resource being locked can be identified by 74855 ("Table") and 0 ("operation")
Error code
ORA-00054
Product
Oracle Database
Versions
Oracle Database 19c, 21c, 23ai and 26ai (wording differs: see below)
Last reviewed
24 October 2026

What it means

ORA-00054 means your statement needed a lock that another session holds and was not allowed to wait for it (NOWAIT, or a lock timeout that ran out), so Oracle returned at once instead of queueing.

Most Oracle statements simply wait when another session holds a lock they need. ORA-00054 appears when waiting is not allowed or the allowed wait has run out: LOCK TABLE ... NOWAIT, SELECT ... FOR UPDATE NOWAIT, and DDL such as ALTER TABLE, DROP TABLE or TRUNCATE on a table with uncommitted changes. For DDL the wait is set by the DDL_LOCK_TIMEOUT parameter, whose default of 0 means NOWAIT.

Current releases rewrite the message to describe the lock: its type and name (TM is the DML lock on a table), and two identifiers. In Oracle's own example the first identifier, described as "Table", is the object number of the locked table. Oracle's reference gives a query on GV$SESSION and GV$LOCK that uses these values to find the session holding the lock and how many seconds it has held it. Oracle Database 19c and 21c print only "resource busy and acquire with NOWAIT specified or timeout expired".

The holder is usually a session with an uncommitted transaction on the table: a developer's SQL tool with an unfinished UPDATE, a batch job, or an application connection that never committed. Once it commits or rolls back, the lock is released and your statement will succeed.

Common causes

  • DDL (ALTER TABLE, DROP TABLE, TRUNCATE, CREATE INDEX without ONLINE) on a table another session has changed but not committed, with DDL_LOCK_TIMEOUT at its default of 0.
  • SELECT ... FOR UPDATE NOWAIT on rows that another transaction has locked.
  • LOCK TABLE ... NOWAIT on a table that another session holds a conflicting lock on.
  • A SQL tool session (SQL Developer, SQL*Plus) left with uncommitted changes, holding locks for a long time.
  • A deployment script that runs DDL while the application is still writing to the table.

Diagnose it

Read-only These queries only read the data dictionary (USER_, ALL_ and DBA_ views) and dynamic performance views (V$). They do not change data, privileges or settings, so they are safe to run first. DBA_ and V$ views need the matching privileges.

Which object is locked? (current message format)

For a TM lock, look up the first identifier from the message in DBA_OBJECTS (or ALL_OBJECTS for objects you can see).

SELECT owner, object_name, object_type
FROM dba_objects
WHERE object_id = 74855;  -- the first identifier from the message
What to look for

The table that is locked. With the 19c message you already know the table from your own statement.

Which sessions hold locks on the table?

V$LOCKED_OBJECT lists the sessions holding DML locks on each object. Needs SELECT access to the V$ views and DBA_OBJECTS, normally a DBA. Oracle's ORA-00054 page gives an equivalent query on GV$SESSION and GV$LOCK that filters on the lock type and the two identifiers from the message, and works across RAC instances.

SELECT s.sid, s.serial#, s.username, s.status, s.osuser, s.machine,
       s.module, s.program, s.logon_time, lo.locked_mode
FROM v$locked_object lo
JOIN dba_objects o ON o.object_id = lo.object_id
JOIN v$session s ON s.sid = lo.session_id
WHERE o.owner = 'SHOP'
  AND o.object_name = 'ORDERS';
What to look for

The session (SID and SERIAL#), the user, the machine and the program holding the lock. A STATUS of INACTIVE with an old LOGON_TIME usually means an idle session with an open transaction.

Is anything already queued behind the holder?

SELECT sid, username, blocking_session, event, seconds_in_wait
FROM v$session
WHERE blocking_session IS NOT NULL;
What to look for

Sessions that are waiting, and the SID blocking each one. If many sessions wait on the same SID, ending that transaction is urgent.

How to fix it

Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.

Let the holding session commit or roll back

Changes data

Oracle's Action is to retry, and if the lock is still held, identify the session and end its transaction. Contact the owner of the session found above and ask them to finish: in their session, not yours.

-- run in the session that holds the lock
COMMIT;    -- or ROLLBACK, if the changes are not wanted

Let DDL wait for the lock instead of failing at once

Changes configuration

DDL_LOCK_TIMEOUT sets how many seconds DDL waits in the DML lock queue; 0 (the default) means NOWAIT. Setting it for your session makes a deployment wait for short transactions to finish instead of failing. If the lock is still held when the time runs out, you get the error again.

ALTER SESSION SET ddl_lock_timeout = 60;

ALTER TABLE shop.orders ADD (notes VARCHAR2(400));

Wait a bounded time for row locks

Changes data

Where code uses NOWAIT, consider WAIT n, which (per the SELECT reference) waits up to n seconds for the rows to become available and then returns control to you; handle the error raised when they are still locked. Keep NOWAIT where an immediate answer is the point, for example to skip a job that is already being processed, and handle the error there.

SELECT id, status
FROM shop.orders
WHERE id = :order_id
FOR UPDATE WAIT 5;

Last resort: end the holding session

Changes database state

Oracle's reference lists disconnecting or terminating the session as an option. Do this only when the owner cannot be reached and the work cannot wait. Use the SID and SERIAL# from the diagnostic query.

Caution: Needs the ALTER SYSTEM privilege. All uncommitted work in that session is rolled back, which for a large transaction can take a long time, and the user or job loses its connection. Check SID and SERIAL# twice: they identify one specific session.

ALTER SYSTEM KILL SESSION '147,41814';

Examples

Altering a table while another session has an uncommitted change

Not reproduced here: no Oracle Database is installed for this site. The result shows the current message format from Oracle's error reference, whose own example is a DROP TABLE blocked by a TM lock; the object number 74855 is illustrative and differs on every database. Oracle Database 19c prints "resource busy and acquire with NOWAIT specified or timeout expired".

-- session 1 (not committed)
UPDATE orders SET status = 'SHIPPED' WHERE id = 42;

-- session 2
ALTER TABLE orders ADD (notes VARCHAR2(400));
Expected result (documented format, not run)
ORA-00054: Failed to acquire a lock (Type: "TM", Name: "DML", Description: "Synchronizes accesses to an object") because it is currently held by another session. The resource being locked can be identified by 74855 ("Table") and 0 ("operation")

SELECT FOR UPDATE NOWAIT on a row another transaction holds

Not reproduced here: no Oracle Database is installed for this site. The result shows the 19c wording from Oracle's error reference. Current releases print the longer "Failed to acquire a lock" form, describing the lock type and its identifiers; that exact text for a row lock is not shown in Oracle's reference, so it is not reproduced here.

-- session 1 (not committed)
UPDATE orders SET status = 'PICKING' WHERE id = 42;

-- session 2
SELECT id, status
FROM orders
WHERE id = 42
FOR UPDATE NOWAIT;
Expected result (documented format, not run)
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

How to prevent it

Run DDL in a maintenance window or with a session DDL_LOCK_TIMEOUT, and check V$LOCKED_OBJECT for open transactions on the table before you start. Commit or roll back in SQL tools as soon as you finish a change, rather than leaving an open transaction in a window you are no longer using.

In application code, use NOWAIT or WAIT n only where you handle ORA-00054 deliberately, for example by skipping a row another worker has already claimed, and keep transactions short so locks are released quickly.

Common questions

How do I find which session is locking my table?

Query V$LOCKED_OBJECT joined to DBA_OBJECTS and V$SESSION for the table, or use Oracle's GV$SESSION and GV$LOCK query with the lock type and identifiers from the current message. You get the SID, SERIAL#, user, machine and program of the holder.

Why does ALTER TABLE fail instantly instead of waiting?

DDL waits only as long as DDL_LOCK_TIMEOUT allows, and its default of 0 means NOWAIT. Set ddl_lock_timeout for your session to let the DDL wait for short transactions.

Should I kill the blocking session?

Only as a last resort. Ending it rolls back all its uncommitted work and disconnects the user or job. First ask the owner to commit or roll back, or wait and retry.

Learn more on CodeWithSQL

Official documentation

Last technically reviewed 24 October 2026; examples and diagnostics run on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally. Messages and explanations follow Oracle's Database Error Messages reference; no Oracle Database was available, so the examples were not run locally.

Still stuck on an Oracle error?

Browse the full Oracle error library, or get hands-on help from an experienced SQL professional.