Jawaban:
Anda dapat melakukan ini dengan DBMS_LOCK
dan kunci eksklusif.
Lihat prosedur berikut:
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;
/
Tes (sesi 1):
SQL> BEGIN
2 myproc();
3 END;
4 /
(Jelas kembali ketika DBMS_LOCK.sleep()
kembali).
Tes (sesi 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>
Jelas Anda harus melakukannya GRANT EXECUTE ON DBMS_LOCK TO YOURUSER;
.
Gunakan tabel 'kunci'.
Ketika prosedur dimulai, periksa tabel untuk nilai yang diketahui, jika tidak ada yang maju dan keluar dari proc. Jika tidak ada, tulis nilai ke tabel, jalankan prosedur, lalu hapus nilai dan keluar seperti biasa.
Ketika klien saya memiliki permintaan yang memiliki logika bisnis unik seperti ini, saya mencoba membalikkan pertanyaan dan menanyakan mengapa ini diperlukan.
Cara terbaik untuk memastikan hanya satu salinan yang berjalan tidak membiarkan pengguna menjalankan prosedur sama sekali. Jika prosedur ini sangat istimewa maka penggunaannya harus dibatasi untuk dba / pengembang.
Cara lain adalah dengan hanya menjalankan prosedur ini sebagai pekerjaan. Tambahkan tanda centang pada prosedur untuk melihat apakah ada pekerjaan yang memanggil ini sedang berjalan. Jika kemudian berhenti diproses lebih lanjut dan catat kejadiannya.