Sudhanshu Kumar, October 17, 2002 - 11:19 pm UTC
Thanks Tom for the loop idea.
But the timing 00:08:14.18 means 8 minutes & 14 seconds.And I think sqlplus have this default format of giving hundreth of a second when we do set timing on. So that means I only waited for 8 minutes.
October 18, 2002 - 8:50 am UTC
DOH -- i read that wrong didn't I.
but yes, dbms_lock.sleep has problems with really large numbers -- the loop will correct that.
DBMS_LOCK package
Denise, October 23, 2003 - 12:02 pm UTC
Hi Tom
I seem to be pestering you alot these days.
I have a lock on a table that I am trying to figure out
how to release.(see v$lock output)
Oracle usercode Oracle SID Serial nbr Object name Lock type F_ground B_groun
------------------------------ ---------- ---------- --------------- ------------- --------- -------
GUI 8 3 MAILING Row-X (SX) 188
SQL> select * from v$lock where sid = 8;
Thu Oct 23
Exclusive locks
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
3A330458 3A330524 8 TX 131138 177618 6 0 6346 0
1D8016AC 1D8016C0 8 TM 65920 0 3 0 6361 0
1D0EAA18 1D0EAA28 8 JQ 0 19148 6 0 6524 0
I ran the dbms_lock.sql to create the dbms_lock package.
I then researched the functions used to allocate,request,convert and release locks.
when I run the dbms_lock.allocate_unique function I keep
getting the following errors.
SQL> EXEC SQL EXECUTE
BEGIN SQL EXECUTE; END;
*
ERROR at line 1:
ORA-06550: line 1, column 11:
PLS-00103: Encountered the symbol "EXECUTE" when expecting one of the following:
%
The symbol "%" was substituted for "EXECUTE" to continue.
SQL> BEGIN
2 DBMS_LOCK.ALLOCATE_UNIQUE (lockname IN VARCHAR2,
3 lockhandle OUT VARCHAR2);
4 END;
5 /
DBMS_LOCK.ALLOCATE_UNIQUE (lockname IN VARCHAR2,
*
ERROR at line 2:
ORA-06550: line 2, column 43:
PLS-00103: Encountered the symbol "VARCHAR2" when expecting one of the following:
(
ORA-06550: line 3, column 55:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
return
I have an ora-00054 "Resource Busy with acquire NOWAIT specified" that I am trying to clear(or release) from the
system)
as always thanks a heap for your time and help.
October 23, 2003 - 1:21 pm UTC
kill session '8,3', thats the only way to release locks in another session
DUH!!!
Denise, October 23, 2003 - 2:35 pm UTC
you know Tom...right after I wrote you I ran this Kill Session script I have that I use to monitor sessions.
I saw that 'locked table' session still hanging out there
and thought...heck...I'm gonna type:
alter system kill session '8,3' immediate;
wa-la the session was slated marked for kill...thought
"ok it's doing the rollback thing..I'll wait awhile"...
looked back and the session was gone and the table was
no longer locked.
Like I said before I always seem to make things
harder than they are...but it's how I learn.
I promise not to pester you(at least for awhile) :~)
regards,
your biggest oracle fan
DBMS_LOCK.SLEEP problems
A reader, June 30, 2005 - 10:05 am UTC
June 30, 2005 - 10:21 am UTC
do you need to sleep for more than 10 minutes?
DBMS_LOCK.SLEEP problems
A reader, July 05, 2005 - 3:44 pm UTC
This is the problem that we are solving by calling SLEEP with much more than 10 minutes:
Audit procedure runs inside of Oracle. Procedure is getting data through webservice calls to some legacy system and then storing data locally in Oracle. Legacy system is available from 6am till 6pm. Audit can run for hours (for really large data sets - even days. Performance is beyond of us - it's all on the legacy system side). We found the easiest way to solve the problem: schedule procedure to run and periodically check current time between webservice calls. When legacy system is unavailable, procedure is just sleeping till next available working window... Please advice if this is a reasonable approach or it can be done smarter.
Thanks a lot!
July 05, 2005 - 3:53 pm UTC
why not just schedule it to run at the next available window? eg: dbms_job.
zero percent chance I would have a session just sleep there for hours on end.
DBMS_LOCK.SLEEP problems
A reader, July 06, 2005 - 2:55 pm UTC
What if this must be done as one transaction?
July 07, 2005 - 8:23 am UTC
you have a transaction that runs for hours and hours and hours or days even???
and you've never had serious rollback/undo segment issues?? really?
dbms_lock.sleep procedure
A reader, July 07, 2005 - 11:17 am UTC
To be honest - no. Audit data retrieved from legacy system is completely isolated and is not used till the audit is done. But I see your concern. So - if I understand you right - you'd definitely prefer splitting such a job to multiple transactions.
By the way - it's typical for this webservice call to run for an hour or more...
July 07, 2005 - 1:36 pm UTC
.... it's typical for this webservice call to run for an hour or more......
wow, thats not a webservice anymore :)
definitely split this into logical units of work -- but I cannot imagine hanging out for hours and hours - the odds that your open transaction fails goes up with every hour (system failure, whatever). I don't know your system -- but I would look at the business logic.
How about for smaller duration?
A reader, May 03, 2006 - 9:58 am UTC
Hi Tom,
How accurate is dbms_lock.sleep with smaller duration?
Please consider the following test case:
Version: 9.2.0.6
create table tmp_test (log_dt date not null, id number not null);
begin
for i in 1..3*60*60 loop
insert into tmp_test (log_dt,id) values (sysdate,1);
commit;
dbms_lock.sleep(1);
end loop;
end;
/
select *
from (select x.*, (log_dt - prev_log_dt) * 24 * 60 * 60 as seconds
from (select lag(log_dt) over(order by log_dt) as prev_log_dt, t.*
from test.tmp_test t
where t.id = 1) x)
where seconds > 1
order by log_dt desc
/
PREV_LOG_DT LOG_DT ID SECONDS
3/5/2006 9:42:37 PM 3/5/2006 9:42:39 PM 1 2
3/5/2006 9:41:26 PM 3/5/2006 9:41:28 PM 1 2
3/5/2006 9:40:30 PM 3/5/2006 9:40:32 PM 1 2
3/5/2006 9:39:38 PM 3/5/2006 9:39:40 PM 1 2
3/5/2006 9:38:32 PM 3/5/2006 9:38:34 PM 1 2
3/5/2006 9:37:26 PM 3/5/2006 9:37:28 PM 1 2
3/5/2006 9:36:24 PM 3/5/2006 9:36:26 PM 1 2
3/5/2006 9:35:38 PM 3/5/2006 9:35:40 PM 1 2
3/5/2006 9:34:23 PM 3/5/2006 9:34:25 PM 1 2
...
Even I can find,
select *
from (select x.*, (log_dt - prev_log_dt) * 24 * 60 * 60 as seconds
from (select lag(log_dt) over(order by log_dt) as prev_log_dt, t.*
from test.tmp_test t
where t.id = 1) x)
where seconds > 2
order by log_dt desc
/
PREV_LOG_DT LOG_DT ID SECONDS
3/5/2006 8:57:28 PM 3/5/2006 8:57:38 PM 1 10
3/5/2006 8:48:25 PM 3/5/2006 8:48:28 PM 1 3
I had also captured v$session_wait for this session in another table for every 5 seconds. During the 10 seconds gap, I see only the following:
LOG_DT SID SEQ# EVENT P1TEXT P1 P1RAW P2TEXT P2 P2RAW P3TEXT P3 P3RAW WAIT_TIME SECONDS_IN_WAIT STATE
3/5/2006 8:57:40 PM 126 19587 PL/SQL lock timer duration 100 0000000000000064 0 00 0 00 0 2 WAITING
3/5/2006 8:57:35 PM 126 19584 PL/SQL lock timer duration 100 0000000000000064 0 00 0 00 0 26 WAITING
3/5/2006 8:57:30 PM 126 19584 PL/SQL lock timer duration 100 0000000000000064 0 00 0 00 0 21 WAITING
3/5/2006 8:57:25 PM 126 19581 PL/SQL lock timer duration 100 0000000000000064 0 00 0 00 0 16 WAITING
The wait event is always this.
Does this mean there is some issue with the database server?
Thanks always.
Regards,
Albert Nelson A.
May 03, 2006 - 1:00 pm UTC
well, the 2 second ones - I'd ignore all of them, just takes a sleep of 1.000000000001 second to cause that (give you are using sysdate with a granularity of 1 second - anything even a TINY BIT over 1 second could be "2 seconds"
according to your wait report - you'd have a bigger than 10 second gap there - look at the 8:57:35 observation - seconds in wait = 26. are you sure that you were looking at the right sessions here.
(also, what is the goal of this test - is dbms_lock.sleep going to be precise within +/- 0.0000000001 seconds - never, nope, doubt it. Will it be "pretty close", yup, yes - absolutely)
Why gap?
Albert Nelson A, May 03, 2006 - 2:15 pm UTC
Hi Tom,
I agree with the 2 seconds gap.
I was also very much puzzled with seconds in wait. But I am sure that this is the correct session.
Actually the goal of the test is as below:
We have a table that is supposed to be inserted with about 50 records per second by the application. Of late, we see for few seconds (about 30 to 40) there are no records in the table. This gap is seen about 20 times daily. We are trying to figure it out what is the root cause of this. Is the application itself not inserting the data or the application is sending the inserts but the database is not doing it? That's why I created this test case.
Your advice will be very much helpful for us.
Thanks always.
Regards,
Albert Nelson A.
May 03, 2006 - 2:54 pm UTC
look in your alert - any "checkpoint not complete" messages there?
No
Albert Nelson A., May 03, 2006 - 9:23 pm UTC
Hi Tom,
There are no error messages in the alert log.
Albert Nelson A.
May 04, 2006 - 2:11 am UTC
that would be the only thing I can think of off of the top of my head - that the database "paused" while dbwr finished a checkpoint OR while arch got caught up (cannot allocate new log messages - the database could "pause" during those events, the inserts would stop).
The information above just isn't adding up - if the session was 26 seconds in wait:
3/5/2006 8:57:35 PM 126 19584 PL/SQL lock timer duration 100
0000000000000064 0 00 0 00 0 26 WAITING
at 8:57:35 - I don't see how this bit of data:
PREV_LOG_DT LOG_DT ID SECONDS
3/5/2006 8:57:28 PM 3/5/2006 8:57:38 PM 1 10
could have been produced by it - because it was asleep at 8:57:28.
Is dbms_lock.sleep uninterruptible?
Roman Filipsky, May 04, 2006 - 6:19 am UTC
Here's the testcase (both 9i and 10g):
Login to sqlplus and do:
exec dbms_lock.sleep(100)
Try to cancel it using CtrlC. It's succesful.
Now when the sleep is placed inside the loop like in:
begin
loop
dbms_lock.sleep(100);
end loop;
end;
/
That block cant be interrupted with CtrlC. The problem is that it cant be interrupted using OCI from another thread as well.
Do you know about any workaround?
May 04, 2006 - 7:41 am UTC
no, i do not.
Time to call support?
Albert Nelson A, May 04, 2006 - 7:32 am UTC
Hi Tom,
Yes I find this anomaly.
Even some times, the session_wait shows a continuous increase in seconds_in_wait but during that time I can find records inserted. I had also confirmed that the session id is the correct one.
LOG_DT SID SEQ# EVENT P1TEXT P1 P1RAW SECONDS_IN_WAIT STATE
3/5/2006 8:47:38 PM 126 18966 PL/SQL lock timer duration 100 0000000000000064 118 WAITING
3/5/2006 8:47:33 PM 126 18961 PL/SQL lock timer duration 100 0000000000000064 113 WAITING
3/5/2006 8:47:28 PM 126 18956 PL/SQL lock timer duration 100 0000000000000064 108 WAITING
3/5/2006 8:47:23 PM 126 18951 PL/SQL lock timer duration 100 0000000000000064 103 WAITING
3/5/2006 8:47:18 PM 126 18946 PL/SQL lock timer duration 100 0000000000000064 98 WAITING
3/5/2006 8:47:13 PM 126 18942 PL/SQL lock timer duration 100 0000000000000064 93 WAITING
3/5/2006 8:47:08 PM 126 18937 PL/SQL lock timer duration 100 0000000000000064 88 WAITING
3/5/2006 8:47:03 PM 126 18932 PL/SQL lock timer duration 100 0000000000000064 83 WAITING
3/5/2006 8:46:58 PM 126 18927 PL/SQL lock timer duration 100 0000000000000064 78 WAITING
3/5/2006 8:46:53 PM 126 18922 PL/SQL lock timer duration 100 0000000000000064 73 WAITING
3/5/2006 8:46:48 PM 126 18917 PL/SQL lock timer duration 100 0000000000000064 68 WAITING
3/5/2006 8:46:43 PM 126 18912 PL/SQL lock timer duration 100 0000000000000064 63 WAITING
3/5/2006 8:46:38 PM 126 18907 PL/SQL lock timer duration 100 0000000000000064 58 WAITING
3/5/2006 8:46:33 PM 126 18902 PL/SQL lock timer duration 100 0000000000000064 53 WAITING
3/5/2006 8:46:28 PM 126 18897 PL/SQL lock timer duration 100 0000000000000064 48 WAITING
3/5/2006 8:46:23 PM 126 18892 PL/SQL lock timer duration 100 0000000000000064 43 WAITING
3/5/2006 8:46:18 PM 126 18887 PL/SQL lock timer duration 100 0000000000000064 38 WAITING
3/5/2006 8:46:13 PM 126 18882 PL/SQL lock timer duration 100 0000000000000064 33 WAITING
3/5/2006 8:46:08 PM 126 18877 PL/SQL lock timer duration 100 0000000000000064 28 WAITING
3/5/2006 8:46:03 PM 126 18872 PL/SQL lock timer duration 100 0000000000000064 23 WAITING
3/5/2006 8:45:58 PM 126 18867 PL/SQL lock timer duration 100 0000000000000064 18 WAITING
3/5/2006 8:45:53 PM 126 18862 PL/SQL lock timer duration 100 0000000000000064 13 WAITING
3/5/2006 8:45:48 PM 126 18858 PL/SQL lock timer duration 100 0000000000000064 8 WAITING
3/5/2006 8:45:43 PM 126 18853 PL/SQL lock timer duration 100 0000000000000064 3 WAITING
Log_dt id
1 3/5/2006 8:47:38 PM 1
2 3/5/2006 8:47:37 PM 1
3 3/5/2006 8:47:35 PM 1
4 3/5/2006 8:47:34 PM 1
5 3/5/2006 8:47:33 PM 1
6 3/5/2006 8:47:32 PM 1
7 3/5/2006 8:47:31 PM 1
8 3/5/2006 8:47:30 PM 1
9 3/5/2006 8:47:29 PM 1
10 3/5/2006 8:47:28 PM 1
... Deleted for brevity
113 3/5/2006 8:45:44 PM 1
114 3/5/2006 8:45:43 PM 1
Time to call support?
Regards,
Albert Nelson A.
May 04, 2006 - 7:54 am UTC
could be - but - do you care in this case? (since it is not the problem you are trying to solve in the first place...)
No.
Albert Nelson A, May 04, 2006 - 8:59 am UTC
Hi Tom,
Actually I don't care for the present case. But just that may be a possible bug be pointed out.
Any other suggestions for finding out the reason for gap?
Thanks always.
Regards,
Albert Nelson A.
May 04, 2006 - 4:37 pm UTC
have you tried the approach you are using against your dummy plsql block against this application (a process to monitor what it is doing from another session)
Analysis
Albert Nelson A, May 05, 2006 - 7:28 am UTC
Hi Tom,
Actually I had captured v$session_wait for all the sessions when I ran the test case.
The application is using connection pool and hence I cannot take identify a particular session.
The application table had seven gaps during that time. I had tried the following query for some gap periods:
select event, count(distinct sid), sum(seconds_in_wait)
from test.sw
where log_dt between
to_date('3/5/2006 8:21:46 PM', 'dd/mm/yyyy hh:mi:ss am') and
to_date('3/5/2006 8:22:49 PM', 'dd/mm/yyyy hh:mi:ss am') and
sid > 11
group by event
/
EVENT COUNT(DISTINCTSID) SUM(SECONDS_IN_WAIT)
PL/SQL lock timer 2 192
SQL*Net message from client 187 6572781
SQL*Net message to client 1 0
buffer busy waits 1 0
db file sequential read 3 0
log file sync 116 0
between
to_date('3/5/2006 8:44:09 PM', 'dd/mm/yyyy hh:mi:ss am') and
to_date('3/5/2006 8:44:59 PM', 'dd/mm/yyyy hh:mi:ss am')
EVENT COUNT(DISTINCTSID) SUM(SECONDS_IN_WAIT)
PL/SQL lock timer 2 620
SQL*Net message from client 201 4688077
SQL*Net message to client 1 0
db file sequential read 1 0
log file sync 126 50
between
to_date('3/5/2006 8:55:03 PM', 'dd/mm/yyyy hh:mi:ss am') and
to_date('3/5/2006 8:55:41 PM', 'dd/mm/yyyy hh:mi:ss am')
EVENT COUNT(DISTINCTSID) SUM(SECONDS_IN_WAIT)
PL/SQL lock timer 2 1656
SQL*Net message from client 221 3646645
SQL*Net message to client 1 0
Does this conclusively prove that application did not sent any insert during that time? Should we concentrate on application / network and rule out database?
Thanks again.
Regards,
Albert Nelson A.
May 05, 2006 - 2:36 pm UTC
no, that doesn't prove anything - could be a connection pool issue though - if the application grabs a connect/does something/releases - the connection pool itself could be the "snag" - there might not have been a connection to grab.
be nice if the application called dbms_application_info to identify itself - v$session could be used to figure out "what session is what" then
equivalent SQLPLUS command
abz, June 06, 2007 - 11:43 am UTC
Is there any equivalent SQLPLUS (not pl/sql) command for
the functionality dbms_lock.sleep provides?
June 06, 2007 - 9:17 pm UTC
no, just pause.
dbms_sleep.lock doesnt work in mount status
abz, June 06, 2007 - 11:55 am UTC
dbms_sleep.lock doesnt executes when called
when the database is is in mount state.
Any solution to this?
Can I use the undocumented DBMS_BACKUP_RESTORE.SLEEP?
because it even works in mount state. Will there be any harm?
June 06, 2007 - 9:18 pm UTC
open the database, not much works in mount but not open state.
what are you trying to do? and why?
I AM USING 10G RELEASE 2
abz, June 06, 2007 - 11:56 am UTC
trying to do this
abz, June 07, 2007 - 4:10 am UTC
Actually, on my primary production database I have
set log_archive_duplex_dest='/mydr_archives', /mydr_archives
is a mapped (using Network File System(NFS)) to another
remote AIX machine.
After every 30 minutes archived are generated and stored
on this location.
On the remote AIX machine I am using
RECOVER AUTOMATIC DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL;
But when sometimes it completes before the new file is
arrived, then it requires me to type the command again
when the file is arrived.
What I want is a .SQL script in which I will do
RECOVER AUTOMATIC DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL;
execute dbms_lock.sleep(600);
RECOVER AUTOMATIC DATABASE USING BACKUP CONTROLFILE UNTIL CANCEL;
execute dbms_lock.sleep(600);
.
.
.
I would liked a pl/sql loop, but RECOVER is an SQL command so it will not work and even if it worked, then in case
of its failure due to unavailability of the file it will
break the loop. (by the way, is there a way I can run SQLPLUS command from a pl/sql block.)?
I know you may recommend to implement DATA GUARD, but this
is not an option for us for some reason.
June 07, 2007 - 2:45 pm UTC
why isn't it an option - of course it is. The right answer is data guard, it IS MOST CERTAINLY AN OPTION.
DBMS_LOCK.SLEEP not working in Mount state
Vikas Khanna, September 26, 2007 - 6:20 am UTC
Hi Tom,
I am trying to flip the Standby from MOUNT to OPEN READ ONLY and vice versa through an automated job, so that query reporting can talk to stanby and can get the reports.
However, while trying to open the database in READ ONLY mode I want to make sure that the difference between the applied VS archived log is not more than 1 log sequence.
If the difference is more than 1, please let the process sleep for 5 mins before checking again from v$managed_standby.
I checked dbms_lock.sleep(n) doesn't work and it says Invalid identifier. Can you please let me know any other way by which a process can be made to sleep for n secs before retrying again the operation when in MOUNTED state.
Thanks
VK
September 26, 2007 - 9:37 pm UTC
are you on unix?
SQL> !sleep <whatever>
would work - on windows - we'd need to find another "sleep" method
Vikas Khanna, September 27, 2007 - 12:47 am UTC
Hi Tom,
We are on unix.
However with in PL/SQL code how do I give a host call to let the process sleep for n secs.
declare
Arch_seq NUMBER := 2;
Mrp_seq NUMBER := 0;
begin
-- To check whether we have Applied Vs Archived Status current as of Primary, if not loop through till they are equal-1
While (Arch_seq - Mrp_seq) > 1 loop
for Check_Process in (Select Process, Max(Sequence#) Seq from V\$managed_standby Where Process != 'RFS' Group by Process)
loop
If Check_Process.Process = 'ARCH' then
arch_seq := Check_Process.Seq;
Else
mrp_seq := Check_Process.Seq;
End if;
end loop;
If (Arch_seq - Mrp_seq) > 1 then
dbms_output.put_line('Date : ' || to_Char(sysdate,'dd/mm/yyyy hh24:mi:ss') || ' Waiting for the logs to be applied the difference being ' || (Arch_seq - Mrp_seq) || ' logs');
--dbms_lock.sleep(120);
Else
dbms_output.put_line ('Date : ' || to_Char(sysdate,'dd/mm/yyyy hh24:mi:ss') || ' No Waiting for the logs to be applied');
exit;
End if;
End loop;
Thanks
September 27, 2007 - 6:53 am UTC
you will not be doing this in plsql - you will have to script this bit using either sqlplus directly or better yet, an OS specific shell script.
plsql is running in the server, it cannot just 'shell out' from your sqlplus session.
Please help
vk, September 28, 2007 - 2:12 am UTC
Hi Tom,
Since, I am not too good at shell scripts, can you please write this for me as it will provide me a good learning platform to move forward in that direction.
Looking for a response.
Thanks
September 28, 2007 - 5:33 pm UTC
this is such an opportunity for you then!
I've always found that a small challenge, something really small and tangible, is a great way to get started.
Me coding a snippet for you - that would not be a good platform to move forward from.
You doing it - that would be.
to vk from INDIA
Tyler, September 28, 2007 - 1:28 pm UTC
How do you expect to get any better at scripting if you get others to do your work for you?
Not trying to be rude, but personally, I'd rather see Tom spending his time helping people with conceptual problems as opposed to doing their homework.
Regards,
Tyler.
To Tyler
Ritesh, September 28, 2007 - 5:29 pm UTC
Not to be harsh!
I think you are acting as you are the boss of Tom, let Tom decide what he has to answer and what not.
It's an open community and people do learn from this site a lot, As VK is having this issue I am also facing the same one.
If Tom is busy then you could help us, if you have the knowledge or else you also learn what Tom has to say.
Thanks,
OPEN to MOUNT State
ritesh, October 05, 2007 - 6:36 am UTC
Hi Tom,
I have written the script in flipping the standby from mount to open (RO) and back from open to mount state.
However the logic states that with in a time frame, if the user session exists doing something, we need to kill and put the database back to mount state for the logs to start applying,
However after killing sessions and initiating the recover manage standby database I am getting this error
ORA-01093: ALTER DATABASE CLOSE only permitted with no sessions connected
Can you please let me know how best to handle this?
V$session entry exists with 'KILLED Status'
ritesh, October 06, 2007 - 5:53 am UTC
Hi Tom,
I checked and found that there is an entry which exists in V$session for that sid which has been killed using 'Alter system kill session ' , ' immediate;
I have also set my sqlnext.expire_time=1 which means that the dead connections (which have been killed) should go off with in a span of 1 minute.
However the session does exist for duration of more than 5 mins till I wrote some SQL statement to get 'your session has been killed' and then the session from V$session went off.
Should sqlnet.expire_time not detect dead sessions and remove their entry from V$session.
Thanks
Please Explain
Bhushan, April 03, 2008 - 11:19 am UTC
Hello Tom,
The concept of Locks seems enchanting :)
Although i have never used it before as a developer neither know who can use it efficiently.
I wrote this piece of code and did see some changes in the dba_ddl_locks view output (using 10g on vista installed 2 days back)which told me atleast the syntax was correct.However i fail to understand how and where it can be used.we neither specify any object or device when requesting a handle? Or is the handle something like a pointer..that is returned from the package and then we use it...dont know myself i am confused.PLease help clarify.
-- Created on 4/3/2008 by BHUSHAN
declare
-- Local variables here
i integer:=180;
test_lock VARCHAR2(100):= 'var1_test_lock';
test_lock_handle VARCHAR2(100);
begin
-- Test statements here
DELETE test WHERE ROWID IN (SELECT ROWID FROM test WHERE rownum < 100);
sys.dbms_lock.allocate_unique(test_lock,test_lock_handle ,i);
dbms_output.put_line(test_lock_handle);
sys.dbms_lock.sleep(60);
end;
Cheers!!!
Bhushan
April 03, 2008 - 9:13 pm UTC
it is like a pointer, a handle...
Thanks
Bhushan, April 04, 2008 - 12:13 pm UTC
Could you please give an example?I have your book but did not carry it with me to Singapore.If you can direct me to any link here we can actually see an example that too would be great..i know the syntax and sementics of how we can get the handle..what i want to know is ocne we get the handle how it can be used...
Cheers!!!
Bhushan
April 04, 2008 - 1:02 pm UTC
you have access to the online documentation? it weighs nothing.
allocate unique just allocates a named lock (you name it)
You use it in your code to control multiple sessions accessing a resource.
Say you wanted to have many sessions write to the same OS file - that would be a mess normally - so you could:
a) allocate unique( 'filename.goes.here', your_handle )
b) request( your_handle, in exclusive mode ) - that serializes
c) open file in append mode, write message, close file
d) release the lock you obtained in b)
A strange story
Paul, April 24, 2008 - 8:51 am UTC
Thanks for the tip re dbms_lock.sleep. My very odd situation combines several of the ideas of this thread.
The problem: an inhouse forms application has a bug where when the user hits the wrong combination of keystrokes a query like this is fired:
select ....
from matched_invoice_line_items W
for update of keyrec_date nowait;
The table has 25 million rows. The W alias seems to be a truncated where clause. This query starts at the beginning of history and locks every row it can, often reading and locking more than 20 million rows before it finds a locked row and must roll back. Generates a lot of redo in a hurry, 3-5gb isn't unusual.
Development hasn't been able to reproduce the bug, Oracle says upgrade your software to supported versions, etc., mgmt has other things to worry about.
The grotesque workaround is to lock the oldest row in the table during working hours, which causes the query-from-hell to fail immediately. The row needs to be locked 13 hours a day.
So in this odd case we have a need for a very long transaction as was mentioned earlier in this thread as well as the need for dbms_lock.sleep - sleep until the window closes and then exit rollback.
It's so ugly that I had to tell someone about it.
simulating job interval through sleep
Gajanan, August 17, 2009 - 9:15 am UTC
Dear Sir,
I have a procedure, which I, have to schedule once every day, But i am not suppose to use dbms_job or dbms_scheduler, so I, am not sure how to create a interval(similar to the one present in dbms_scheduler), so I plan to do something similar to
loop
pl/sql
dbms_lock.sleep(86400);
end loop;
Question 1) Will giving such a long sleep period create issue.
Question 2) Is there any other alternative?
thank you.
August 24, 2009 - 8:51 am UTC
...But i am not
suppose to use dbms_job or dbms_scheduler, ...
so, why are you asking me? The only way to schedule jobs inside the database is....
dbms_job
dbms_scheduler
your approach will never work - since once you shutdown the database your anonymous block goes away.
You know the correct way
dbms_job
dbms_scheduler
there is no reason to NOT use them, use them.
Session state and dbms_lock.sleep
A reader, September 29, 2010 - 10:38 am UTC
Tom,
My assumption is that when you call dbms_lock.sleep that you are actually "doing some work" as far as the session is concerned, you are not idle.
Is this true or not or when you call sleep does Oracle interpret this time as idle ?
Thanks for your response.
September 29, 2010 - 10:58 am UTC
your session is active (v$session.status) but you are in an idle wait event (you only incur wait events when active - you are actively waiting :) )
DBMS_LOCK
A Reader, December 15, 2010 - 5:23 am UTC
Hi Tom,
Would it not be better to leave locking to Oracle itself instead of implementing it using DBM_LOCK? Are there any advantages or is it aimed to be used for specific purposes only.
Thanks
December 15, 2010 - 11:21 am UTC
it is aimed to be used for special cases only - most people will never have a need for it.
dbms_lock is useful when you need to impose serialization on some process - when you have some shared resource not protected by normal enqueue (row) locks. For example - maybe you have a logging routine you built - it logs to a file. You have decided that all of your processes should log to the same file (maybe they just write start/end times or something like that). dbms_lock would be useful to ensure that only one transaction at a time tried to open the file/write it/close it.
dbms_lock from Expert one-on-one Oracle
Rajeshwaran, Jeyabal, January 24, 2011 - 8:45 am UTC
Tom:
I am reading about dbms_lock API from Expert one-on-one Oracle Appendix AG: DBMS_LOCK.
tkyte@TKYTE816> create or replace trigger demo_bifer
2 before insert on demo
3 for each row
4 declare
5 l_lock_id number;
6 resource_busy exception;
7 pragma exception_init( resource_busy, -54 );
8 begin
9 l_lock_id :=
10 dbms_utility.get_hash_value( to_char( :new.x ), 0, 1024 );
11
12 if ( dbms_lock.request
13 ( id => l_lock_id,
14 lockmode => dbms_lock.x_mode,
15 timeout => 0,
16 release_on_commit => TRUE ) = 1 )
17 then
18 raise resource_busy;
19 end if;
20 end;
21 /
Trigger created
I tried the same without using
dbms_utility.get_hash_valuerajesh@ORCL> create table t(x number primary key);
Table created.
Elapsed: 00:00:00.40
rajesh@ORCL>
rajesh@ORCL> create or replace trigger t_trig
2 before insert on T
3 for each row
4 declare
5 l_num number;
6 resource_busy exception;
7 pragma exception_init(resource_busy,-54);
8 begin
9
10 if ( dbms_lock.request(
11 id => :new.x,
12 lockmode => dbms_lock.x_mode,
13 timeout =>0,
14 release_on_commit=>true
15 ) = 1
16 ) then
17 raise resource_busy;
18 end if;
19 end;
20 /
Trigger created.
Elapsed: 00:00:00.09
rajesh@ORCL>
rajesh@ORCL> insert into t(x) values (1);
1 row created.
Elapsed: 00:00:00.07
rajesh@ORCL>
And, in the Session-2 I got this
rajesh@ORCL> insert into t(x) values (1);
insert into t(x) values (1)
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
ORA-06512: at "RAJESH.T_TRIG", line 14
ORA-04088: error during execution of trigger 'RAJESH.T_TRIG'
Elapsed: 00:00:00.00
rajesh@ORCL>
Question:1) Is that
dbms_utility.get_hash_value is really needed to get this Non-Blocking fashion?
February 01, 2011 - 10:25 am UTC
I wrote in there I used get_hash_value so I would generate at MOST 1024 locks as enqueue resources are a "resource" and a resource you could run out of.
You can generate an infinite number of locks in theory.
That was what I was trying to avoid.
My goal: good concurrency (small chance of a hash collision on different keys) and good resource utilization.
Facing Prob with DBMS_LOCK.SLEEP
Ajay Gupta, May 06, 2011 - 1:32 am UTC
Hi Guys,
I am Ajay here. I have 3 years of exp in Oracle SQL and PL/SQL.
Please let me know solution for my issue.
I am getting error while compiling procedure in which it is used DBMS_LOCK.sleep (600);
Error(102,10): PLS-00201: identifier 'DBMS_LOCK' must be declared.
Clarifications regarding calling sleep in a proc for long hours of sleep
ORAcle devloper, May 25, 2015 - 11:35 am UTC
create procedure my_sleep( SLEEP_TIME IN NUMBER )
as
begin
for i in 1 .. trunc( SLEEP_TIME/600 )
loop
dbms_lock.sleep( 600 );
end loop;
dbms_lock.sleep( SLEEP_TIME-trunc(SLEEP_TIME/600)*600 );
end;
/
------------------------------------
can we use this proc in the answer for even sleep of 6 to 10 hours without any issue?
Sleep in mount
Laurent Schneider, June 12, 2023 - 6:32 am UTC
Hi :)
Just landed there looking for a sleep in mount.
I came up with using my 1980's C64 BASIC skills
for i in 1 to 10 next i
Sleep 5 seconds on your standby
alter session set PLSQL_OPTIMIZE_LEVEL=0;
for i in 1..1e9 loop null; end loop;
Best regards
Laurent
June 12, 2023 - 12:45 pm UTC
Thanks for sharing
Sleep in mount
Laurent Schneider, June 12, 2023 - 2:18 pm UTC
or simply DBMS_BACKUP_RESTORE.SLEEP(10) ;-)
Note 1296382.1