กระทำจำเป็นหลังจากการดำเนินการ DML ในฟังก์ชั่น / ขั้นตอนหรือไม่?


20

ฉันสงสัยว่าถ้าจำเป็นต้องเขียนคอมมิทหลังจากใส่ / ลบ / อัพเดทในฟังก์ชั่น / ขั้นตอนหรือไม่

ตัวอย่าง:

create or replace function test_fun
return number is
begin
   delete from a;
   return 0;
end;

หรือขั้นตอน

create or replace procedure aud_clear_pro
as
begin
   delete from a;
end;

มันจำเป็นต้องกระทำหลังจากลบ?

ไม่เข้าใจสถานการณ์ต่อไปนี้:

  1. ถ้าฉันเรียก function / procedure จากหน้าต่าง SQL มันต้องยอมรับ

    แต่

  2. หากฉันกำหนดเวลาฟังก์ชั่น / ขั้นตอนโดยใช้ dbms_scheduler และเรียกใช้งานคำสั่งลบจะถูกส่งโดยอัตโนมัติ

    ทำไม?

คำตอบ:


24

โดยทั่วไปขั้นตอนไม่ควรกระทำ การตัดสินใจควบคุมธุรกรรมประเภทนั้นควรจะถูกทิ้งไว้ที่รหัสระดับสูงกว่าซึ่งจะรู้ได้ว่าเมื่อการทำธุรกรรมเชิงตรรกะเสร็จสมบูรณ์จริง ๆ แล้ว หากคุณกระทำภายในโพรซีเดอร์ที่เก็บไว้คุณกำลัง จำกัด การนำกลับมาใช้ใหม่ได้เนื่องจากผู้โทรที่ต้องการการเปลี่ยนแปลงโพรซีเดอร์ทำให้เป็นส่วนหนึ่งของธุรกรรมที่มีขนาดใหญ่กว่าไม่สามารถเรียกขั้นตอนนี้ได้โดยตรง

หากคุณเรียกขั้นตอนแบบโต้ตอบคุณจะต้องยอมรับหรือย้อนกลับธุรกรรมอย่างชัดเจนเนื่องจาก Oracle ไม่ทราบว่าคุณตั้งใจจะให้ขั้นตอนการโทรเป็นธุรกรรมเชิงตรรกะหรือหากคุณต้องการเขียนธุรกรรมขนาดใหญ่ที่เกี่ยวข้องกับการเรียกกระบวนการหลายครั้ง ถ้าคุณใช้dbms_scheduler, dbms_schedulerอนุมานว่างานเป็นรายการตรรกะและกระทำในตอนท้ายของงานสมมติว่ามันเป็นที่ประสบความสำเร็จ ( dbms_jobจะเป็นสิ่งเดียวกัน)

ฟังก์ชั่นไม่ควรจัดการข้อมูลในตอนแรก ฟังก์ชั่นที่จัดการกับข้อมูลไม่สามารถเรียกใช้จากคำสั่ง SQL (ยกเว้นกรณีมุมซึ่งฟังก์ชันนั้นถูกประกาศให้ใช้ธุรกรรมอัตโนมัติซึ่งแทบจะไม่เหมาะสม) จุดทั้งหมดของการมีทั้งฟังก์ชั่นและโพรซีเดอร์คือฟังก์ชั่นนั้นสามารถฝังอยู่ในคำสั่ง SQL และสามารถมอบให้กับผู้ใช้ได้อย่างอิสระมากขึ้นเพราะพวกเขาจะไม่เปลี่ยนแปลงข้อมูลใด ๆ


1
Oracle ไม่สามารถให้ผู้โทรเริ่มต้นธุรกรรมที่ผูกการเรียกโพรซีเดอร์ได้หรือไม่? ใน SQL Server คุณสามารถคอมมิชชันภายในโพรซีเดอร์ได้ แต่ถ้าผู้เรียกเปิดธุรกรรมก่อนที่จะเรียกโพรซีเดอร์นั้นจะไม่มีอะไรเกิดขึ้นจนกว่าผู้เรียกจะคอมมิตด้วย
Nick Chammas

4
@NickChammas - Oracle ไม่มีแนวคิดเกี่ยวกับธุรกรรมซ้อน หากโพรซีเดอร์ยอมรับทุกสิ่งที่ผู้เรียกทำจนถึงจุดนั้นจะยอมรับ ผู้เรียกเริ่มต้นการทำธุรกรรมโดยปริยายด้วยคำสั่งแรก (ไม่ว่าจะเป็นการเรียกขั้นตอนหรืออย่างอื่น) ดังนั้นมันควรจะขึ้นอยู่กับผู้โทรที่จะจบการทำธุรกรรม
Justin Cave

@JustinCave ในขณะที่เป็นจริงอย่าลืมเกี่ยวกับการทำธุรกรรมของตนเอง
Philᵀᴹ

@Phil - จริง แต่นั่นเป็นสัตว์ที่แตกต่างกันมาก ธุรกรรมอิสระไม่สามารถเห็นการเปลี่ยนแปลงที่ไม่ได้รับการกำหนดโดยผู้เรียกและไม่สามารถย้อนกลับโดยผู้โทรดังนั้นจึงไม่น่าเป็นไปได้อย่างยิ่งที่จะมีสิ่งอื่นใดนอกเหนือจากกระบวนการบันทึกควรถูกประกาศให้ใช้ธุรกรรมอัตโนมัติ
Justin Cave

4

เพื่อตอบคำถามของคุณ ทำไม?

ตอนนี้คุณคงทราบแล้วเนื่องจากโพสต์นี้มีอายุ 2 ปี แต่ฉันจะตอบสนองเพียงเพื่อบันทึก

เหตุผล # 1 ต้องการการส่งมอบและ # 2 ไม่ได้เป็นเพราะการตั้งค่าฐานข้อมูลเริ่มต้นใน Oracle คือการทำธุรกรรมเมื่อสิ้นสุดเซสชัน หากคุณอยู่ใน sqlplus และเรียกใช้รหัสของคุณด้วยตนเองมันจะไม่ทำธุรกรรมทันที หากคุณออกคำสั่งอย่างชัดเจนหรือคุณออกจาก sqlpus ธุรกรรมนั้นจะส่งมอบ

เหตุผลที่คุณได้รับการยืนยันอัตโนมัติใน # 2 เป็นเพราะสร้างเซสชันเพื่อเรียกใช้สคริปต์ของคุณ เมื่อมันเสร็จสมบูรณ์มันออกจากระบบโดยอัตโนมัติซึ่งจะทำให้การกระทำอัตโนมัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.