Ошибка ora 00054 resource busy and acquire with nowait specified or timeout expired

Why am I getting this database error when I update a table?

ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

Josep's user avatar

Josep

4952 gold badges6 silver badges16 bronze badges

asked Jan 30, 2011 at 11:59

sun's user avatar

1

Your table is already locked by some query. For example, you may have executed «select for update» and have not yet committed/rollbacked and fired another select query. Do a commit/rollback before executing your query.

Paweł Obrok's user avatar

Paweł Obrok

22.5k8 gold badges74 silver badges70 bronze badges

answered Jan 30, 2011 at 12:02

user258367's user avatar

user258367user258367

3,2372 gold badges18 silver badges17 bronze badges

4

from here ORA-00054: resource busy and acquire with NOWAIT specified

You can also look up the sql,username,machine,port information and get to the actual process which holds the connection

SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME,
S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT 
FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, 
V$PROCESS P, V$SQL SQ 
WHERE L.OBJECT_ID = O.OBJECT_ID 
AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR 
AND S.SQL_ADDRESS = SQ.ADDRESS;

Community's user avatar

answered Aug 10, 2012 at 3:29

Abey Tom's user avatar

Abey TomAbey Tom

1,4261 gold badge12 silver badges7 bronze badges

5

Please Kill Oracle Session

Use below query to check active session info

SELECT
    O.OBJECT_NAME,
    S.SID,
    S.SERIAL#,
    P.SPID,
    S.PROGRAM,
    SQ.SQL_FULLTEXT,
    S.LOGON_TIME
FROM
    V$LOCKED_OBJECT L,
    DBA_OBJECTS O,
    V$SESSION S,
    V$PROCESS P,
    V$SQL SQ
WHERE
    L.OBJECT_ID = O.OBJECT_ID
    AND L.SESSION_ID = S.SID
    AND S.PADDR = P.ADDR
    AND S.SQL_ADDRESS = SQ.ADDRESS;

kill like

alter system kill session 'SID,SERIAL#';

(For example, alter system kill session '13,36543';)

Reference
http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html

user5670895's user avatar

answered Feb 10, 2014 at 11:01

Chan Myae Thu's user avatar

Chan Myae ThuChan Myae Thu

1,0541 gold badge9 silver badges9 bronze badges

4

There is a very easy work around for this problem.

If you run a 10046 trace on your session (google this… too much to explain). You will see that before any DDL operation Oracle does the following:

LOCK TABLE ‘TABLE_NAME’ NO WAIT

So if another session has an open transaction you get an error. So the fix is… drum roll please. Issue your own lock before the DDL and leave out the ‘NO WAIT’.

Special Note:

if you are doing splitting/dropping partitions oracle just locks the partition.
— so yo can just lock the partition subpartition.

So…
The following steps fix the problem.

  1. LOCK TABLE ‘TABLE NAME’; — you will ‘wait’ (developers call this hanging). until the session with the open transaction, commits. This is a queue. so there may be several sessions ahead of you. but you will NOT error out.
  2. Execute DDL. Your DDL will then run a lock with the NO WAIT. However, your session has aquired the lock. So you are good.
  3. DDL auto-commits. This frees the locks.

DML statements will ‘wait’ or as developers call it ‘hang’ while the table is locked.

I use this in code that runs from a job to drop partitions. It works fine. It is in a database that is constantly inserting at a rate of several hundred inserts/second. No errors.

if you are wondering. Doing this in 11g. I have done this in 10g before as well in the past.

answered Apr 29, 2013 at 21:15

Bob's user avatar

BobBob

2,4964 gold badges21 silver badges18 bronze badges

8

This error happens when the resource is busy. Check if you have any referential constraints in the query. Or even the tables that you have mentioned in the query may be busy. They might be engaged with some other job which will be definitely listed in the following query results:

SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'

Find the SID,

SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id

answered Jul 15, 2013 at 8:28

Arunchunaivendan's user avatar

3

In my case, I was quite sure it was one of my own sessions which was blocking. Therefore, it was safe to do the following:

  • I found the offending session with:

    SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';

    The session was inactive, but it still held the lock somehow. Note, that you may need to use some other WHERE condition in your case (e.g. try USERNAME or MACHINE fields).

  • Killed the session using the ID and SERIAL# acquired above:

    alter system kill session '<id>, <serial#>';

Edited by @thermz: If none of the previous open-session queries work try this one. This query can help you to avoid syntax errors while killing sessions:

  • SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'

answered Sep 3, 2013 at 10:27

wrygiel's user avatar

wrygielwrygiel

5,0703 gold badges24 silver badges29 bronze badges

1

This happens when a session other than the one used to alter a table is holding a lock likely because of a DML (update/delete/insert). If you are developing a new system, it is likely that you or someone in your team issues the update statement and you could kill the session without much consequence. Or you could commit from that session once you know who has the session open.

If you have access to a SQL admin system use it to find the offending session. And perhaps kill it.

You could use v$session and v$lock and others but I suggest you google how to find that session and then how to kill it.

In a production system, it really depends. For oracle 10g and older, you could execute

LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);

In a separate session but have the following ready in case it takes too long.

alter system kill session '....

It depends on what system do you have, older systems are more likely to not commit every single time. That is a problem since there may be long standing locks. So your lock would prevent any new locks and wait for a lock that who knows when will be released. That is why you have the other statement ready. Or you could look for PLSQL scripts out there that do similar things automatically.

In version 11g there is a new environment variable that sets a wait time. I think it likely does something similar to what I described. Mind you that locking issues don’t go away.

ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);

Finally it may be best to wait until there are few users in the system to do this kind of maintenance.

answered Jul 15, 2013 at 19:49

Arturo Hernandez's user avatar

Arturo HernandezArturo Hernandez

2,7293 gold badges28 silver badges35 bronze badges

2

select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;
   
   ALTER SYSTEM KILL SESSION 'sid,serial#';

answered Sep 26, 2019 at 17:52

harun ugur's user avatar

harun ugurharun ugur

1,69818 silver badges17 bronze badges

As mentioned in other answers, this error is caused by concurrent DML operations running in other sessions. This causes Oracle to fail to lock the table for DDL with the default NOWAIT option.

For those without admin permissions in the database or who cannot kill/interrupt the other sessions, you can also precede your DDL operation with:

alter session set DDL_LOCK_TIMEOUT = 30;
--Run your DDL command, e.g.: alter table, etc.

I was receiving this error repeatedly in a database with background jobs doing large insert/update operations, and altering this parameter in the session allowed the DDL to continue after a few seconds of waiting for the lock.

For further information, see the comment from rshdev on this answer, this entry on oracle-base or the official docs on DDL_LOCK_TIMEOUT.

answered Aug 27, 2021 at 18:40

divieira's user avatar

divieiradivieira

8859 silver badges17 bronze badges

1

Just check for process holding the session and Kill it. Its back to normal.

Below SQL will find your process

SELECT s.inst_id,
   s.sid,
   s.serial#,
   p.spid,
   s.username,
   s.program FROM   gv$session s
   JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id;

Then kill it

ALTER SYSTEM KILL SESSION 'sid,serial#'

OR

some example I found online seems to need the instance id as well
alter system kill session ‘130,620,@1’;

answered Nov 27, 2014 at 3:30

Mathavan John's user avatar

I had this error happen when I had 2 scripts I was running. I had:

  • A SQL*Plus session connected directly using a schema user account (account #1)
  • Another SQL*Plus session connected using a different schema user account (account #2), but connecting across a database link as the first account

I ran a table drop, then table creation as account #1.
I ran a table update on account #2’s session. Did not commit changes.
Re-ran table drop/creation script as account #1. Got error on the drop table x command.

I solved it by running COMMIT; in the SQL*Plus session of account #2.

answered May 23, 2017 at 19:46

vapcguy's user avatar

vapcguyvapcguy

7,0401 gold badge56 silver badges51 bronze badges

2

I managed to hit this error when simply creating a table! There was obviously no contention problem on a table that didn’t yet exist. The CREATE TABLE statement contained a CONSTRAINT fk_name FOREIGN KEY clause referencing a well-populated table. I had to:

  • Remove the FOREIGN KEY clause from the CREATE TABLE statement
  • Create an INDEX on the FK column
  • Create the FK

answered Nov 19, 2015 at 15:05

bwperrin's user avatar

bwperrinbwperrin

6605 silver badges12 bronze badges

2

I solved this problem by closing one of my IDE tabs.

PL/SQL Developer
Version 10.0.5.1710

answered Sep 1, 2022 at 14:26

Alexander Martins's user avatar

I also face the similar Issue. Nothing programmer has to do to resolve this error. I informed to my oracle DBA team. They kill the session and worked like a charm.

answered Jan 17, 2017 at 20:50

Shakeer Hussain's user avatar

Shakeer HussainShakeer Hussain

2,1827 gold badges27 silver badges52 bronze badges

3

Solution given by Shashi’s link is the best… no needs to contact dba or someone else

make a backup

create table xxxx_backup as select * from xxxx;

delete all rows

delete from xxxx;
commit;

insert your backup.

insert into xxxx (select * from xxxx_backup);
commit;

answered Mar 27, 2013 at 9:23

tafibo's user avatar

2

Why am I getting this database error when I update a table?

ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

Josep's user avatar

Josep

4952 gold badges6 silver badges16 bronze badges

asked Jan 30, 2011 at 11:59

sun's user avatar

1

Your table is already locked by some query. For example, you may have executed «select for update» and have not yet committed/rollbacked and fired another select query. Do a commit/rollback before executing your query.

Paweł Obrok's user avatar

Paweł Obrok

22.5k8 gold badges74 silver badges70 bronze badges

answered Jan 30, 2011 at 12:02

user258367's user avatar

user258367user258367

3,2372 gold badges18 silver badges17 bronze badges

4

from here ORA-00054: resource busy and acquire with NOWAIT specified

You can also look up the sql,username,machine,port information and get to the actual process which holds the connection

SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME,
S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT 
FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, 
V$PROCESS P, V$SQL SQ 
WHERE L.OBJECT_ID = O.OBJECT_ID 
AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR 
AND S.SQL_ADDRESS = SQ.ADDRESS;

Community's user avatar

answered Aug 10, 2012 at 3:29

Abey Tom's user avatar

Abey TomAbey Tom

1,4261 gold badge12 silver badges7 bronze badges

5

Please Kill Oracle Session

Use below query to check active session info

SELECT
    O.OBJECT_NAME,
    S.SID,
    S.SERIAL#,
    P.SPID,
    S.PROGRAM,
    SQ.SQL_FULLTEXT,
    S.LOGON_TIME
FROM
    V$LOCKED_OBJECT L,
    DBA_OBJECTS O,
    V$SESSION S,
    V$PROCESS P,
    V$SQL SQ
WHERE
    L.OBJECT_ID = O.OBJECT_ID
    AND L.SESSION_ID = S.SID
    AND S.PADDR = P.ADDR
    AND S.SQL_ADDRESS = SQ.ADDRESS;

kill like

alter system kill session 'SID,SERIAL#';

(For example, alter system kill session '13,36543';)

Reference
http://abeytom.blogspot.com/2012/08/finding-and-fixing-ora-00054-resource.html

user5670895's user avatar

answered Feb 10, 2014 at 11:01

Chan Myae Thu's user avatar

Chan Myae ThuChan Myae Thu

1,0541 gold badge9 silver badges9 bronze badges

4

There is a very easy work around for this problem.

If you run a 10046 trace on your session (google this… too much to explain). You will see that before any DDL operation Oracle does the following:

LOCK TABLE ‘TABLE_NAME’ NO WAIT

So if another session has an open transaction you get an error. So the fix is… drum roll please. Issue your own lock before the DDL and leave out the ‘NO WAIT’.

Special Note:

if you are doing splitting/dropping partitions oracle just locks the partition.
— so yo can just lock the partition subpartition.

So…
The following steps fix the problem.

  1. LOCK TABLE ‘TABLE NAME’; — you will ‘wait’ (developers call this hanging). until the session with the open transaction, commits. This is a queue. so there may be several sessions ahead of you. but you will NOT error out.
  2. Execute DDL. Your DDL will then run a lock with the NO WAIT. However, your session has aquired the lock. So you are good.
  3. DDL auto-commits. This frees the locks.

DML statements will ‘wait’ or as developers call it ‘hang’ while the table is locked.

I use this in code that runs from a job to drop partitions. It works fine. It is in a database that is constantly inserting at a rate of several hundred inserts/second. No errors.

if you are wondering. Doing this in 11g. I have done this in 10g before as well in the past.

answered Apr 29, 2013 at 21:15

Bob's user avatar

BobBob

2,4964 gold badges21 silver badges18 bronze badges

8

This error happens when the resource is busy. Check if you have any referential constraints in the query. Or even the tables that you have mentioned in the query may be busy. They might be engaged with some other job which will be definitely listed in the following query results:

SELECT * FROM V$SESSION WHERE STATUS = 'ACTIVE'

Find the SID,

SELECT * FROM V$OPEN_CURSOR WHERE SID = --the id

answered Jul 15, 2013 at 8:28

Arunchunaivendan's user avatar

3

In my case, I was quite sure it was one of my own sessions which was blocking. Therefore, it was safe to do the following:

  • I found the offending session with:

    SELECT * FROM V$SESSION WHERE OSUSER='my_local_username';

    The session was inactive, but it still held the lock somehow. Note, that you may need to use some other WHERE condition in your case (e.g. try USERNAME or MACHINE fields).

  • Killed the session using the ID and SERIAL# acquired above:

    alter system kill session '<id>, <serial#>';

Edited by @thermz: If none of the previous open-session queries work try this one. This query can help you to avoid syntax errors while killing sessions:

  • SELECT 'ALTER SYSTEM KILL SESSION '''||SID||','||SERIAL#||''' immediate;' FROM V$SESSION WHERE OSUSER='my_local_username_on_OS'

answered Sep 3, 2013 at 10:27

wrygiel's user avatar

wrygielwrygiel

5,0703 gold badges24 silver badges29 bronze badges

1

This happens when a session other than the one used to alter a table is holding a lock likely because of a DML (update/delete/insert). If you are developing a new system, it is likely that you or someone in your team issues the update statement and you could kill the session without much consequence. Or you could commit from that session once you know who has the session open.

If you have access to a SQL admin system use it to find the offending session. And perhaps kill it.

You could use v$session and v$lock and others but I suggest you google how to find that session and then how to kill it.

In a production system, it really depends. For oracle 10g and older, you could execute

LOCK TABLE mytable in exclusive mode;
alter table mytable modify mycolumn varchar2(5);

In a separate session but have the following ready in case it takes too long.

alter system kill session '....

It depends on what system do you have, older systems are more likely to not commit every single time. That is a problem since there may be long standing locks. So your lock would prevent any new locks and wait for a lock that who knows when will be released. That is why you have the other statement ready. Or you could look for PLSQL scripts out there that do similar things automatically.

In version 11g there is a new environment variable that sets a wait time. I think it likely does something similar to what I described. Mind you that locking issues don’t go away.

ALTER SYSTEM SET ddl_lock_timeout=20;
alter table mytable modify mycolumn varchar2(5);

Finally it may be best to wait until there are few users in the system to do this kind of maintenance.

answered Jul 15, 2013 at 19:49

Arturo Hernandez's user avatar

Arturo HernandezArturo Hernandez

2,7293 gold badges28 silver badges35 bronze badges

2

select
   c.owner,
   c.object_name,
   c.object_type,
   b.sid,
   b.serial#,
   b.status,
   b.osuser,
   b.machine
from
   v$locked_object a,
   v$session b,
   dba_objects c
where
   b.sid = a.session_id
and
   a.object_id = c.object_id;
   
   ALTER SYSTEM KILL SESSION 'sid,serial#';

answered Sep 26, 2019 at 17:52

harun ugur's user avatar

harun ugurharun ugur

1,69818 silver badges17 bronze badges

As mentioned in other answers, this error is caused by concurrent DML operations running in other sessions. This causes Oracle to fail to lock the table for DDL with the default NOWAIT option.

For those without admin permissions in the database or who cannot kill/interrupt the other sessions, you can also precede your DDL operation with:

alter session set DDL_LOCK_TIMEOUT = 30;
--Run your DDL command, e.g.: alter table, etc.

I was receiving this error repeatedly in a database with background jobs doing large insert/update operations, and altering this parameter in the session allowed the DDL to continue after a few seconds of waiting for the lock.

For further information, see the comment from rshdev on this answer, this entry on oracle-base or the official docs on DDL_LOCK_TIMEOUT.

answered Aug 27, 2021 at 18:40

divieira's user avatar

divieiradivieira

8859 silver badges17 bronze badges

1

Just check for process holding the session and Kill it. Its back to normal.

Below SQL will find your process

SELECT s.inst_id,
   s.sid,
   s.serial#,
   p.spid,
   s.username,
   s.program FROM   gv$session s
   JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id;

Then kill it

ALTER SYSTEM KILL SESSION 'sid,serial#'

OR

some example I found online seems to need the instance id as well
alter system kill session ‘130,620,@1’;

answered Nov 27, 2014 at 3:30

Mathavan John's user avatar

I had this error happen when I had 2 scripts I was running. I had:

  • A SQL*Plus session connected directly using a schema user account (account #1)
  • Another SQL*Plus session connected using a different schema user account (account #2), but connecting across a database link as the first account

I ran a table drop, then table creation as account #1.
I ran a table update on account #2’s session. Did not commit changes.
Re-ran table drop/creation script as account #1. Got error on the drop table x command.

I solved it by running COMMIT; in the SQL*Plus session of account #2.

answered May 23, 2017 at 19:46

vapcguy's user avatar

vapcguyvapcguy

7,0401 gold badge56 silver badges51 bronze badges

2

I managed to hit this error when simply creating a table! There was obviously no contention problem on a table that didn’t yet exist. The CREATE TABLE statement contained a CONSTRAINT fk_name FOREIGN KEY clause referencing a well-populated table. I had to:

  • Remove the FOREIGN KEY clause from the CREATE TABLE statement
  • Create an INDEX on the FK column
  • Create the FK

answered Nov 19, 2015 at 15:05

bwperrin's user avatar

bwperrinbwperrin

6605 silver badges12 bronze badges

2

I solved this problem by closing one of my IDE tabs.

PL/SQL Developer
Version 10.0.5.1710

answered Sep 1, 2022 at 14:26

Alexander Martins's user avatar

I also face the similar Issue. Nothing programmer has to do to resolve this error. I informed to my oracle DBA team. They kill the session and worked like a charm.

answered Jan 17, 2017 at 20:50

Shakeer Hussain's user avatar

Shakeer HussainShakeer Hussain

2,1827 gold badges27 silver badges52 bronze badges

3

Solution given by Shashi’s link is the best… no needs to contact dba or someone else

make a backup

create table xxxx_backup as select * from xxxx;

delete all rows

delete from xxxx;
commit;

insert your backup.

insert into xxxx (select * from xxxx_backup);
commit;

answered Mar 27, 2013 at 9:23

tafibo's user avatar

2

Thanks for the info user ‘user712934’

You can also look up the sql,username,machine,port information and get to the actual process which holds the connection

SELECT O.OBJECT_NAME, S.SID, S.SERIAL#, P.SPID, S.PROGRAM,S.USERNAME,
S.MACHINE,S.PORT , S.LOGON_TIME,SQ.SQL_FULLTEXT 
FROM V$LOCKED_OBJECT L, DBA_OBJECTS O, V$SESSION S, 
V$PROCESS P, V$SQL SQ 
WHERE L.OBJECT_ID = O.OBJECT_ID 
AND L.SESSION_ID = S.SID AND S.PADDR = P.ADDR 
AND S.SQL_ADDRESS = SQ.ADDRESS;

ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired error occurs when you try to lock a resource that is already locked and busy with execution. If two Oracle connections attempt to lock a resource such as a table, view, or other resource, the first connection will lock the resource, and the second resource will be unable to obtain the lock for the resource. The error will be thrown immediately if the NOWAIT option is used to obtain the lock. If the WAIT option is used to obtain the lock, the lock command will wait until the timeout expires and then throw an error ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

The error will be displayed to Oracle users who attempt to execute a LOCK TABLE or SELECT FOR UPDATE command with the NOWAIT keyword.
If the user waits a few minutes before attempting to run the query again, the active session will have completed and the error message will not reappear. Another option is to find the active session and terminate it in order to free up the table and rerun the query. Reduce the likelihood of this error occurring in the future. Make the table read-only if it will not be used for inserting, updating, or deleting data.

The Problem

If two Oracle database sessions attempt to obtain a lock on a resource, one will obtain the lock for updating, while the other will throw this error. Two Oracle database connections must be created to reproduce this error. Execute the lock command for a table in the first session. With a write operation, the table will be locked. When you attempt to obtain a lock from the second session, the lock will throw this error.

Session 1

lock table employee in exclusive mode NOWAIT;

Session 1 output

Lock succeeded.

Session 2

lock table employee in exclusive mode NOWAIT;

Session 2 output

lock table employee in exclusive mode NOWAIT
Error report -
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
00054. 00000 -  "resource busy and acquire with NOWAIT specified or timeout expired"
*Cause:    Interested resource is busy.
*Action:   Retry if necessary or increase timeout.

Solution 1

When you run an Oracle query from the application, the lock is created before the query is executed. When the query execution is finished, it will either be committed or rolled back. The second thread will attempt to lock the same resource as the first thread during concurrent access from the application. This will result in the error. If this error occurs, modify your code to retry after a certain amount of time. This will fix the problem. In this case, the first lock will be completed after the query is executed.

Solution 2

If the error occurs from your application and the error is consistently reproducible, then the commit or rollback is not happening. Verify in your code make sure commit is done after successful execution. In case of failure, the roll back should be called explicitly. The commit or roll back will unlock the table for another oracle user to use.

Session 1

lock table employee in exclusive mode NOWAIT;

Session 1 output

Lock succeeded.

Session 2

lock table employee in exclusive mode NOWAIT;

Session 2 output

lock table employee in exclusive mode NOWAIT
Error report -
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
00054. 00000 -  "resource busy and acquire with NOWAIT specified or timeout expired"
*Cause:    Interested resource is busy.
*Action:   Retry if necessary or increase timeout.

Session 1

rollback;

Session 1 output

Rollback complete.

Session 2

lock table employee in exclusive mode NOWAIT;

Session 2 output

Lock succeeded.

Solution 3

The table is not required to lock if it is locked to execute a select statement for reading purposes. The table can be defined as read-only. Reduce the likelihood of this errors happening again in the future. If the table will not be used for inserting, updating, or deleting data, make it read-only.

alter table employee read only;

Execute the following command to restore the read-only table.

alter table employee read write;

Solution 4

If you are receiving the error from the second session of the application and are unable to obtain control of the first, you will be unable to execute commit or roll back to release the lock. The first session should be ended in this case by terminating the session. There are two ways to end a session: POST TRANSACTION and IMMEDIATE. After completing the current transaction, the POST TRANSACTION will terminate the session. The IMMEDIATE transaction will end the current session immediately without waiting for the current transaction to finish. The transactions will be rolled back in this case.

To identify the session that needs to be terminated, run the below command. the query will return the Sid and serial number.

select a.sid, a.serial# from v$session a, v$locked_object b, dba_objects c
where b.object_id = c.object_id and a.sid = b.session_id and OBJECT_NAME='EMPLOYEE';

Output

sid.    serial#
----------------
25      64920

The following command will terminate the session and the lock will be released.

alter system kill session '<Sid>, <serial>' POST_TRANSACTION | IMMEDIATE ;
alter system kill session '25, 64920' IMMEDIATE ;

or

alter system kill session '25, 64920' POST_TRANSACTION ;

Solution 5

If the first session query takes longer to complete and the second session executes before the first session is finished, the first session cannot be terminated. The first session is valid, and the second session should be postponed until the first session is finished. The second session should be set to wait until the first session is finished. For the lock timeout expiry, the timeout configuration should be increased. The following command will set the lock’s timeout. The lock command should not use the NOWAIT option in this case.

alter session set ddl_lock_timeout = 600;

Session 1

lock table employee in exclusive mode;

Session 1 output

Lock succeeded.

Session 2

lock table employee in exclusive mode;

Session 2 output

-- wait for a long period till the first session to complete

Session 1

rollback;

Session 1 output

Rollback complete.

Session 2

-- wait for a long period till the first session to complete

Session 2 output

Lock succeeded.

.

April 10, 2020

Sometimes you can get ” ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired ” error.

ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

When you run any DDL ( alter, drop, truncate ), LOCK TABLE or SELECT FOR UPDATE, you can get this error.

ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

Cause: Interested resource is busy.

Action: Retry if necessary or increase timeout.
SQL> ALTER TABLE MSD.TEST_TABLE ADD (name varchar2(30));

ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

resource busy and acquire with NOWAIT specified or timeout expired

DDL_LOCK_TIMEOUT

To solve this problem, you can use DDL_LOCK_TIMEOUT parameter with related query as follows.

ALTER SESSION SET DDL_LOCK_TIMEOUT=6000;

ALTER TABLE MSD.TEST_TABLE ADD (name varchar2(30));

or You can kill the blocking and locking sessions.

You can list which objects are holding and blocking the others with the following script.

SELECT
O.OBJECT_NAME,
S.SID,
S.SERIAL#,
P.SPID,
S.PROGRAM,
SQ.SQL_FULLTEXT,
S.LOGON_TIME
FROM
GV$LOCKED_OBJECT L,
DBA_OBJECTS O,
V$SESSION S,
V$PROCESS P,
V$SQL SQ
WHERE
L.OBJECT_ID = O.OBJECT_ID
AND L.SESSION_ID = S.SID
AND S.PADDR = P.ADDR
AND S.SQL_ADDRESS = SQ.ADDRESS;

If you get the same error even though you use DDL_LOCK_TIMEOUT parameter, then you should use the following query to find the related session which hold this table.

SELECT a.inst_id,
status,
username,
machine,
event,
blocking_session,
sql_id,
last_call_et,
status,
'alter system kill session ''' || a.sid || ',' || serial# || ''';'
FROM gv$access a, gv$session b
WHERE a.inst_id = b.inst_id AND a.sid = b.sid
AND object = 'TEST_TABLE';

query result is as follows. You can run the following scripts to kill related sessions.

alter system kill session '489,46242,@5';
alter system kill session '824,41709,@4';
alter system kill session '877,15892,@7';

You can use the following query to find the blocking session according to related Schema.

SELECT c.owner,
c.object_name,
c.object_type,
b.sid,
b.serial#,
b.inst_id,
b.status,
b.osuser,
b.machine,'alter system kill session ''' || b.sid || ',' || b.serial# || ',@'|| b.inst_id ||''';'
FROM gv$locked_object a, gv$session b, dba_objects c
WHERE b.sid = a.session_id AND a.object_id = c.object_id and c.owner= 'SCHEMA_NAME';

Once you kill the related sessions, you can alter the table as follows.

SQL> ALTER TABLE MSD.TEST_TABLE ADD (name varchar2(30));

Table altered.


Do you want to learn Oracle Database for Beginners, then Click and read the following articles.

Oracle Database Tutorials for Beginners ( Junior Oracle DBA )

 2,788 views last month,  1 views today

About Mehmet Salih Deveci

I am Founder of SysDBASoft IT and IT Tutorial and Certified Expert about Oracle & SQL Server database, Goldengate, Exadata Machine, Oracle Database Appliance administrator with 10+years experience.I have OCA, OCP, OCE RAC Expert Certificates I have worked 100+ Banking, Insurance, Finance, Telco and etc. clients as a Consultant, Insource or Outsource.I have done 200+ Operations in this clients such as Exadata Installation & PoC & Migration & Upgrade, Oracle & SQL Server Database Upgrade, Oracle RAC Installation, SQL Server AlwaysOn Installation, Database Migration, Disaster Recovery, Backup Restore, Performance Tuning, Periodic Healthchecks.I have done 2000+ Table replication with Goldengate or SQL Server Replication tool for DWH Databases in many clients.If you need Oracle DBA, SQL Server DBA, APPS DBA,  Exadata, Goldengate, EBS Consultancy and Training you can send my email adress [email protected].-                                                                                                                                                                                                                                                 -Oracle DBA, SQL Server DBA, APPS DBA,  Exadata, Goldengate, EBS ve linux Danışmanlık ve Eğitim için  [email protected] a mail atabilirsiniz.

  • Ошибка or tapsh 08 при добавлении карты гугл pay
  • Ошибка or pmia 14 что это
  • Ошибка origin nfs 2016
  • Ошибка ordinal expression expected
  • Ошибка order not found