ที่เกิดขึ้นจากคำถามที่เกี่ยวข้องนี้ที่ฉันต้องการทราบวิธีการบังคับให้สองธุรกรรมเกิดขึ้นตามลำดับในกรณีที่ไม่สำคัญ (ซึ่งทั้งสองทำงานในแถวเดียวเท่านั้น) ฉันได้รับคำตอบ - ใช้SELECT ... FOR UPDATE
เป็นบรรทัดแรกของธุรกรรมทั้งสอง - แต่สิ่งนี้นำไปสู่ปัญหา: หากการทำธุรกรรมครั้งแรกไม่ได้กระทำหรือย้อนกลับธุรกรรมที่สองจะถูกปิดกั้นอย่างไม่มีกำหนด innodb_lock_wait_timeout
ตัวแปรกำหนดจำนวนวินาทีหลังจากที่ลูกค้าพยายามที่จะทำให้การทำธุรกรรมที่สองจะได้รับการบอกว่า "ขออภัยลองอีกครั้ง" ... แต่เท่าที่ผมสามารถบอกพวกเขาต้องการจะพยายามอีกครั้งจนกว่ารีบูตเซิร์ฟเวอร์ถัดไป ดังนั้น:
- แน่นอนว่าจะต้องมีวิธีการบังคับ
ROLLBACK
ถ้าธุรกรรมใช้เวลานาน? ฉันต้องหันไปใช้ daemon เพื่อฆ่าธุรกรรมดังกล่าวหรือไม่และถ้าใช่ daemon นั้นจะมีลักษณะอย่างไร - หากการเชื่อมต่อถูกฆ่าตายโดย
wait_timeout
หรือinteractive_timeout
mid-transaction ธุรกรรมจะถูกย้อนกลับหรือไม่? มีวิธีทดสอบสิ่งนี้จากคอนโซลหรือไม่?
Clarification : innodb_lock_wait_timeout
ตั้งค่าจำนวนวินาทีที่ธุรกรรมจะรอการปลดล็อคก่อนที่จะยอมแพ้ สิ่งที่ฉันต้องการคือวิธีการบังคับให้ล็อคเพื่อปลดล็อค
อัปเดต 1 : ต่อไปนี้เป็นตัวอย่างง่ายๆที่แสดงให้เห็นว่าเหตุใดจึงinnodb_lock_wait_timeout
ไม่เพียงพอเพื่อให้แน่ใจว่าการทำธุรกรรมครั้งที่สองไม่ได้ถูกบล็อกโดยรายการแรก:
START TRANSACTION;
SELECT SLEEP(55);
COMMIT;
ด้วยการตั้งค่าเริ่มต้นของinnodb_lock_wait_timeout = 50
ธุรกรรมนี้เสร็จสมบูรณ์โดยไม่มีข้อผิดพลาดหลังจาก 55 วินาที และถ้าคุณเพิ่มUPDATE
ก่อนSLEEP
บรรทัดให้เริ่มต้นธุรกรรมครั้งที่สองจากลูกค้ารายอื่นที่พยายามSELECT ... FOR UPDATE
แถวเดียวกันนั่นเป็นธุรกรรมที่สองที่หมดเวลาไม่ใช่รายการที่หลับไป
สิ่งที่ฉันกำลังมองหาคือวิธีที่จะยุติการนอนหลับพักผ่อนของธุรกรรมนี้
อัปเดต 2 : เพื่อตอบสนองต่อข้อกังวลของ hobodave เกี่ยวกับความเป็นจริงของตัวอย่างด้านบนนี่คือสถานการณ์จำลองทางเลือก: DBA เชื่อมต่อกับเซิร์ฟเวอร์ที่ใช้งานจริงและทำงานอยู่
START TRANSACTION
SELECT ... FOR UPDATE
โดยที่บรรทัดที่สองล็อคแถวที่แอปพลิเคชันเขียนบ่อยๆ จากนั้น DBA จะถูกขัดจังหวะและเดินออกไปโดยลืมที่จะจบธุรกรรม แอปพลิเคชั่นจะหยุดทำงานจนกว่าจะปลดล็อคแถว ฉันต้องการลดเวลาที่แอปพลิเคชันติดค้างเนื่องจากข้อผิดพลาดนี้
ROLLBACK
ทำธุรกรรมครั้งแรกหากใช้เวลานานกว่าn
วินาทีเพื่อให้เสร็จสมบูรณ์ มีวิธีการทำเช่นนั้น?
MYSQL
ไม่มีการกำหนดค่าเพื่อป้องกันสถานการณ์นี้ เพราะมันไม่เป็นที่ยอมรับของเซิร์ฟเวอร์แฮงค์เนื่องจากลูกค้าขาดความรับผิดชอบ ฉันไม่พบปัญหาในการเข้าใจคำถามของคุณ แต่อย่างใดมันเกี่ยวข้องกันมาก