เราจำเป็นต้องตรวจสอบให้แน่ใจว่ามีเพียงหนึ่งสำเนาของกระบวนการเฉพาะที่ทำงานใน Oracle ถ้ามันกำลังทำงานอยู่และผู้ใช้พยายามที่จะเปิดอีกมันก็ควรผิดพลาด
วิธีที่ดีที่สุดในการทำเช่นนี้คืออะไร?
เราจำเป็นต้องตรวจสอบให้แน่ใจว่ามีเพียงหนึ่งสำเนาของกระบวนการเฉพาะที่ทำงานใน Oracle ถ้ามันกำลังทำงานอยู่และผู้ใช้พยายามที่จะเปิดอีกมันก็ควรผิดพลาด
วิธีที่ดีที่สุดในการทำเช่นนี้คืออะไร?
คำตอบ:
คุณสามารถทำได้ด้วยDBMS_LOCK
และล็อคพิเศษ
ดูขั้นตอนต่อไปนี้:
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;
/
ทดสอบ (เซสชั่น 1):
SQL> BEGIN
2 myproc();
3 END;
4 /
(เห็นได้ชัดว่าผลตอบแทนเมื่อDBMS_LOCK.sleep()
กลับมา)
ทดสอบ (เซสชัน 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>
GRANT EXECUTE ON DBMS_LOCK TO YOURUSER;
เห็นได้ชัดว่าคุณจะต้อง
ใช้ตาราง 'ล็อค'
เมื่อโพรซีเดอร์เริ่มตรวจสอบตารางสำหรับค่าที่ทราบว่าหากไม่มีให้ดำเนินการเพิ่มเติมและออกจาก proc หากไม่มีให้เขียนค่าลงในตารางดำเนินการขั้นตอนจากนั้นลบค่าและออกตามปกติ
เมื่อลูกค้าของฉันมีคำขอที่มีตรรกะทางธุรกิจที่ไม่เหมือนใครฉันลองเปลี่ยนคำถามและถามว่าทำไมสิ่งนี้ถึงต้องการ
วิธีที่ดีที่สุดเพื่อให้แน่ใจว่ามีการเรียกใช้สำเนาเดียวเท่านั้นที่จะไม่ให้ผู้ใช้ดำเนินการตามขั้นตอนทั้งหมด หากโพรซีเดอร์นี้มีความพิเศษดังนั้นจึงควรใช้ dba / ผู้พัฒนา
อีกวิธีหนึ่งคือเรียกใช้โพรซีเดอร์นี้เป็นงานเท่านั้น เพิ่มการตรวจสอบในกระบวนการเพื่อดูว่ามีงานใด ๆ ที่โทรมาทำงานนี้หรือไม่ หากพวกเขาจะหยุดการประมวลผลเพิ่มเติมและบันทึกเหตุการณ์ที่เกิดขึ้น