การทำธุรกรรมภายในการทำธุรกรรม


18

PostgreSQL จะแสดงพฤติกรรมแบบใดถ้าตัวอย่างสคริปต์ด้านล่างนี้ถูกเรียกใช้

BEGIN;
SELECT * FROM foo;
INSERT INTO foo(name) VALUES ('bar');
BEGIN; <- The point of interest
END;

PostgreSQL จะยกเลิกรายการที่สองBEGINหรือไม่หรือจะมีการตัดสินใจกระทำโดยนัยจากนั้นเรียกใช้BEGIN ENDบล็อกในตอนท้ายว่าเป็นรายการแยกต่างหาก

คำตอบ:


13

สิ่งที่คุณจะต้องมีคือ "ธุรกรรมอิสระ" (คุณลักษณะที่จัดทำโดย oracle) ณ จุดนี้ยังไม่สามารถทำได้ใน PostgreSQL อย่างไรก็ตามคุณสามารถใช้SAVEPOINT s:

BEGIN;
INSERT ...
SAVEPOINT a;
some error;
ROLLBACK TO SAVEPOINT a;
COMMIT;

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

มิฉะนั้นจะไม่มีวิธีแก้ปัญหาอื่นที่สมเหตุสมผลในตอนนี้


13

คุณสามารถลองด้วยตัวคุณเอง:

คำเตือน: มีการทำธุรกรรมที่กำลังดำเนินการอยู่

มันเริ่มต้นไม่มีธุรกรรม (ย่อย) ใหม่เนื่องจากการทำธุรกรรมที่ซ้อนกันจะไม่ถูกนำมาใช้ใน PostgreSQL (คุณอาจทำเวทมนต์ในpl/pgsqlฟังก์ชั่นเช่นเลียนแบบพฤติกรรมนั้น)

ด้วย PostgreSQL 11 เราสามารถคิดได้ว่าขั้นตอนการจัดเก็บจริงใหม่และความสามารถในการจัดการธุรกรรมจะทำให้การทำธุรกรรมซ้อนกันเป็นไปได้ อย่างไรก็ตามตามเอกสารนี้ไม่ใช่กรณี:

ในขั้นตอนการอุทธรณ์ตามCALLคำสั่งเช่นเดียวกับในบล็อกรหัสที่ไม่ระบุชื่อ ( DOคำสั่ง) มันเป็นไปได้ที่จะทำธุรกรรม end โดยใช้คำสั่งและCOMMIT ROLLBACKธุรกรรมใหม่จะเริ่มต้นโดยอัตโนมัติหลังจากที่ธุรกรรมสิ้นสุดลงโดยใช้คำสั่งเหล่านี้ดังนั้นจึงไม่มีคำสั่งเริ่มต้นธุรกรรมที่แยกต่างหาก


9

PostgreSQL ไม่รองรับการทำธุรกรรมย่อย แต่SAVEPOINTคุณสมบัติสามารถตอบสนองความต้องการของคุณได้อย่างมีประสิทธิภาพ การอ้างอิงจากเอกสารสำหรับAdvanced access layer ถึง PG ผ่านสัญญาโดยVitaly Tomilovบน GitHub:

PostgreSQL ไม่ได้มีการสนับสนุนที่เหมาะสมสำหรับการทำธุรกรรมที่ซ้อนกันจะสนับสนุนเฉพาะrollbacks บางส่วนผ่านsavepointsภายในการทำธุรกรรม ความแตกต่างระหว่างสองเทคนิคนี้มีขนาดใหญ่มากดังอธิบายเพิ่มเติม

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

Savepoints สามารถใช้สำหรับการย้อนกลับบางส่วนถึงจุดก่อนหน้าภายในธุรกรรมที่ใช้งานอยู่ ตัวอย่างเช่นในการสร้าง savepoint และเลิกทำเอฟเฟกต์ของคำสั่งทั้งหมดที่ดำเนินการหลังจากสร้างแล้ว:

BEGIN;
    INSERT INTO table1 VALUES (1);
    SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (2);
    ROLLBACK TO SAVEPOINT my_savepoint;
    INSERT INTO table1 VALUES (3);
COMMIT;

ธุรกรรมข้างต้นจะแทรกค่า 1 และ 3 แต่ไม่ใช่ 2 ดูSAVEPOINTเอกสารประกอบสำหรับข้อมูลเพิ่มเติม


0

สำหรับ Postgresql 9.5 หรือใหม่กว่าคุณสามารถใช้ผู้ทำงานเบื้องหลังแบบไดนามิกที่จัดเตรียมโดยส่วนขยาย pg_background มันสร้างธุรกรรมอัตโนมัติ โปรดดูหน้า GitHubของส่วนขยาย การแก้ปัญหานั้นดีกว่า db_link มีคำแนะนำฉบับสมบูรณ์เกี่ยวกับการสนับสนุนการทำธุรกรรมด้วยตนเองใน PostgreSQL

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