Yanıtlar:
Bunu DBMS_LOCK
özel bir kilitle yapabilirsiniz.
Aşağıdaki prosedüre bakın:
CREATE OR REPLACE PROCEDURE myproc
IS
lockhandle VARCHAR2(128);
retcode NUMBER;
BEGIN
DBMS_LOCK.ALLOCATE_UNIQUE('myproclock',lockhandle);
retcode:=DBMS_LOCK.REQUEST(lockhandle,timeout=>0, lockmode=>DBMS_LOCK.x_mode);
IF retcode<>0
THEN
raise_application_error(-20000,'myproc is already running');
END IF;
/* sleep so that we can test with a 2nd execution */
DBMS_LOCK.sleep(1000);
retcode:=DBMS_LOCK.RELEASE(lockhandle);
END myproc;
/
Test (1. oturum):
SQL> BEGIN
2 myproc();
3 END;
4 /
(Açıkça geri döndüğünde DBMS_LOCK.sleep()
döner).
Test (oturum 2):
SQL> BEGIN
2 myproc();
3 END;
4 /
BEGIN
*
ERROR at line 1:
ORA-20000: myproc is already running
ORA-06512: at "PHIL.MYPROC", line 12
ORA-06512: at line 2
SQL>
Açıkçası ihtiyacın var GRANT EXECUTE ON DBMS_LOCK TO YOURUSER;
.
Bir 'kilit' tablosu kullanın.
Prosedür başladığında, bilinen bir değer için tabloyu kontrol edin, varsa daha ileri gitmeyin ve proc'tan çıkın. Değilse, değeri tabloya yazın, yordamı yürütün, ardından değeri silin ve normal şekilde çıkın.
Müşterilerimin böyle bir iş mantığı olan bir isteği olduğunda, soruyu tersine çevirmeye ve bunun neden gerekli olduğunu sormaya çalışıyorum.
Yalnızca bir kopyanın çalıştığından emin olmanın en iyi yolu, kullanıcıların yordam üzerinde hiç işlem yapmalarına izin vermektir. Bu prosedür çok özelse, kullanımı dba / geliştiricilerle sınırlandırılmalıdır.
Başka bir yol, bu prosedürü yalnızca bir iş olarak çalıştırmaktır. Bunu çağıran işlerin çalışıp çalışmadığını görmek için prosedüre bir kontrol ekleyin. Eğer öyleyse, daha sonraki işlemeyi durdurun ve oluşumu günlüğe kaydedin.