ใน postgres ปลอดภัยหรือไม่ที่จะ (ผิด) ใช้ลำดับชั่วคราว (เซสชันในเครื่อง) เป็นลำดับในเครื่องของธุรกรรม

ฉันอยากมีตัวนับที่จะรีเซ็ตเป็น 0 ทุกครั้งที่เริ่มธุรกรรมใหม่ ฉันต้องการให้ค่าของตัวนับนั้นถูกใช้ในทริกเกอร์บางตัว เนื่องจากลำดับชั่วคราวของ postgres เป็นเซสชันในเครื่อง ฉันจึงสามารถใช้ลำดับหนึ่งเป็นตัวนับของฉันได้ก็ต่อเมื่อไม่มีความเป็นไปได้ที่ธุรกรรม 2 รายการจะทำงานแบบ "ขนาน" ในเซสชันเดียวกัน สิ่งนี้ปลอดภัยที่จะถือว่าใน Postgres หรือไม่ (สิ่งที่ฉันมีอยู่ในใจที่ทำให้ฉันรู้สึกไม่แน่ใจคือสถานการณ์เช่นธุรกรรมอัตโนมัติใน Oracle ในสถานการณ์นั้นอ็อบเจ็กต์โลคัลเซสชันของฉันจะถูกแชร์โดยธุรกรรมภายนอกและธุรกรรมอัตโนมัติภายในซึ่งจะทำลายตำแหน่งธุรกรรมของวัตถุที่ฉันต้องการ .)

ฉันรู้ว่าฉันสามารถใช้ตาราง TEMP โดยมี ON COMMIT DROP หรือ DELETE ROWS ได้ แต่ฉันต้องการทราบว่าลำดับชั่วคราวจะเพียงพอหรือไม่ อย่างน้อยก็ใน postgres


person Paralife    schedule 06.12.2011    source แหล่งที่มา
comment
ดังนั้นคำถามของคุณคืออะไร? ปลอดภัยไหม? ไม่เฉพาะเจาะจงเพียงพอ คุณต้องการบรรลุอะไร?   -  person Erwin Brandstetter    schedule 07.12.2011
comment
ฉันต้องการทราบว่าเซสชันโลคัลออบเจ็กต์สามารถเข้าถึงได้มากกว่า 1 ธุรกรรมในเวลาเดียวกันด้วยวิธีที่เป็นไปได้หรือไม่ ฉันอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับบริบทของคำถามของฉัน ขออภัยหากไม่ชัดเจน   -  person Paralife    schedule 07.12.2011


คำตอบ (1)


ปัจจุบัน PostgreSQL ไม่รองรับธุรกรรมแบบขนานหรือแบบอัตโนมัติ ดังนั้นธุรกรรม session == และลำดับชั่วคราวของเซสชันภายในจะสามารถเข้าถึงได้โดยธุรกรรมเดียวเท่านั้นในแต่ละครั้ง

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

ปัจจุบันก็ปลอดภัยแล้ว (หากตีความสิ่งที่คุณต้องการได้อย่างถูกต้อง)

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

คุณสามารถทำได้ตอนนี้ถ้าคุณต้องการ ใช้ฟังก์ชัน txid_current() เพื่อรับ ID ธุรกรรมปัจจุบัน

แก้ไข: ไม่ txid จะไม่เปลี่ยนแปลงระหว่างเซฟพอยต์

regress=> begin;
BEGIN
regress=> SELECT txid_current();
 txid_current 
--------------
       346947
(1 row)

regress=> savepoint test;
SAVEPOINT
regress=> SELECT txid_current();
 txid_current 
--------------
       346947
(1 row)

แม้ว่าฉันเดาว่ามันต้องอาศัยรายละเอียดการใช้งาน

person Craig Ringer    schedule 07.12.2011
comment
ฉันคิดอย่างนั้น แต่ฉันไม่ได้ทำเพราะฉันรู้สึกว่า txid เปลี่ยนแปลงไปตามจุดบันทึก เรื่องนี้ไม่เป็นความจริงเหรอ? - person Paralife; 07.12.2011
comment
@Paralife: นอกจากนี้ การทำงานด้วยตัวระบุแบบไดนามิกทำให้ยากต่อการใช้คุณสมบัติ เช่น ค่าเริ่มต้นของคอลัมน์หรือ SQL ที่ไม่ใช่ไดนามิก - person Erwin Brandstetter; 07.12.2011
comment
txid ไม่เปลี่ยนแปลงในเซฟพอยต์ - ดูด้านบน หากคุณกังวลเรื่องนั้น คุณสามารถสร้างตัวระบุจาก txid และ CURRENT_TIMESTAMP ได้ (ตามที่ได้รับการแก้ไขเมื่อเริ่มต้น txn) [แก้ไข: นั่นไร้สาระ; txid จะยังคงเปลี่ยนแปลง คุณไม่สามารถใช้การประทับเวลา เพียง ในกรณีที่ txns สองรายการเริ่มต้นพร้อมกันจนถึงความละเอียดของตัวจับเวลา ฮึ. เพียงแค่พึ่งพา txid ที่จะไม่เปลี่ยนแปลงและทดสอบการอัพเกรดให้ดี!] ฉันไม่คิดว่ามันจะสวยเป็นพิเศษ แต่คุณสามารถรวมไว้ในฟังก์ชัน SQL แบบง่าย ๆ เพื่อให้ง่ายต่อการใช้งานในค่าเริ่มต้นและในรูปแบบที่ไม่ใช่ไดนามิก SQL ตามที่ Erwin กล่าวถึงว่าเป็นข้อกังวล - person Craig Ringer; 09.12.2011