การตัดการเชื่อมต่อเครือข่ายหยุดการสืบค้นหรือไม่


13

ฉันเพิ่งดำเนินการแบบสอบถามแบบใช้ปรับปรุงข้อมูลกับระเบียน 100,000 รายการ ฉันรู้ว่าฉันทำผิดพลาดในขณะที่แบบสอบถามกำลังทำงานและถอดสายเคเบิลเครือข่ายอย่างรวดเร็ว

ทำแบบสอบถามการปรับปรุงหรือไม่

  1. หยุดการประมวลผลและย้อนกลับอย่างสมบูรณ์หรือไม่
  2. ดำเนินการต่อไปจนแล้วเสร็จและส่งมอบหรือไม่
  3. หยุดการประมวลผลและออกจากแถวเป้าหมายเพียงบางส่วนเท่านั้นหรือไม่

2
เมื่อแบบสอบถามพบเซิร์ฟเวอร์เซิร์ฟเวอร์จะดำเนินการต่อไปจนกว่าคุณจะยกเลิกแบบสอบถามบนเซิร์ฟเวอร์
JP Chauhan


1
ความคิดเห็นของ Martin ให้คำตอบสำหรับคำถามของคุณ robocop โดยตรง หากเครือข่ายแจ้งให้เซิร์ฟเวอร์ SQL ทราบถึงการยกเลิกการเชื่อมต่อก่อนที่แบบสอบถามของคุณจะทำงานเสร็จสิ้น SQL Server จะย้อนกลับ มิฉะนั้นถ้าแบบสอบถามเสร็จสมบูรณ์ก่อนที่จะมีการบอก SQL Server ว่ามีการยกเลิกการเชื่อมต่อเครือข่ายแล้วจะมีการยืนยัน ไม่ว่าในกรณีใด (สมมติว่าคุณเขียนข้อความค้นหาอัปเดตเดียว) SQL Server จะดำเนินการอัพเดทบางส่วน
Nick Chammas

คำตอบ:


22

ตามที่ Nick และ Martin กล่าวไว้สถานะของแบบสอบถามของคุณขึ้นอยู่กับว่า SQL Server รู้เกี่ยวกับการดึงสายเคเบิลเครือข่ายของคุณก่อนที่แบบสอบถามจะเสร็จสมบูรณ์หรือไม่ จากBooks Online (แม้ว่าฉันจะพบว่ามันน่าสนใจที่มีหัวข้อเทียบเท่าในปี 2000 , 2005 , 2008 , และ2008 R2แต่ไม่ใช่ 2012 หรือ 2014):

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

(นอกเหนือจากนั้นคำว่าการเชื่อมต่อในประโยคสุดท้ายที่ 2 อาจหมายถึงการทำธุรกรรมฉันไม่รู้ว่าจะย้อนกลับหนึ่งการเชื่อมต่อได้อย่างไร)

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

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

UPDATE dbo.sometable 
-- where *oops* I forgot this part

มีสิ่งนี้:

BEGIN TRANSACTION;

UPDATE dbo.sometable
-- where *oops* I forgot this part

-- COMMIT TRANSACTION;
-- ROLLBACK TRANSACTION;

จากนั้นหากการอัปเดตนั้นถูกต้องคุณสามารถเน้นCOMMITส่วนและเรียกใช้งานได้ หากไม่เป็นเช่นนั้นคุณสามารถเน้นส่วนที่ใจเย็นROLLBACKและดำเนินการนั้นได้ คุณสามารถใช้ Add-in เช่นSSMS Tools Packเพื่อแก้ไขNew Queryเทมเพลตของคุณเพื่อรวมสำเร็จรูปได้

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

และแน่นอนเช่นเคยมีการสำรองข้อมูลที่คุณวางใจได้


5
นี่เป็นคำแนะนำที่ยอดเยี่ยมและจัดการปัญหารากของปัญหา OP แต่จริงๆแล้วมันไม่ได้ตอบคำถามว่าแบบสอบถามทำงานต่อเนื่องหรือไม่
Nick Chammas

3
ขอบคุณ @ นิคแรงจูงใจของฉันคือการแก้ไขสาเหตุ (ซึ่งกระตุ้นคำถาม) ไม่ใช่อาการ แต่ฉันได้อัปเดตคำตอบแล้ว
Aaron Bertrand

8

@Aaron ถูกต้อง การสร้างธุรกรรมก่อนคำสั่งของคุณคือทางออกที่ดีที่สุดของคุณ หากคุณจำไม่ได้ว่าจะทำอย่างนั้นแล้วทางเลือกหนึ่งคือการไปเข้าสู่การตั้งค่าและเปิดTools-Options SET IMPLICIT_TRANSACTIONSสิ่งนี้จะเริ่มต้นธุรกรรมโดยอัตโนมัติทันทีที่คำสั่งบางอย่างทำงาน ซึ่งรวมถึงการUPDATE, DELETEฯลฯ ซึ่งดูเหมือนจะเป็นรายการที่ค่อนข้างสมบูรณ์ของคำสั่งใด ๆ ที่จะ"change"มีอะไรบางอย่าง SELECTรวมอยู่ในรายการและwillเริ่มทำธุรกรรม คุณสามารถดูรายการเต็มรูปแบบของคำสั่งที่เริ่มต้นการทำธุรกรรมนี้จะตั้งค่าที่นี่ จะไม่สร้างธุรกรรมหากมีการเริ่มต้นแล้ว ตอนนี้ข้อเสียคือคุณจะต้องจำไว้COMMITหลังจากการเปลี่ยนแปลงใด ๆ

หมายเหตุ: ตามคำแนะนำของ @ Aaron ฉันจะเน้นย้ำเรื่องนี้อีกครั้ง

This is very important!  You will have to remember to COMMIT after any change made!

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

ป้อนคำอธิบายรูปภาพที่นี่


ที่จริงแล้ว: SELECT จะเริ่มทำธุรกรรม (ซึ่งมีการบันทึกไว้ในลิงก์ที่คุณโพสต์ด้วย)
a_horse_with_no_name

ขอบคุณ @a_horse_with_no_name สำหรับการจับสิ่งนั้น! ฉันไม่ได้อ่านอย่างละเอียดเพียงพอและกำลังจะออกจากความทรงจำเก่า (นั่นเป็นความผิดที่เห็นได้ชัด)
Kenneth Fisher

1
นี่เป็นโพสต์ที่มีประโยชน์ แต่จริง ๆ แล้วมันไม่ได้ตอบคำถามของ OP ว่าแบบสอบถามทำงานอย่างต่อเนื่องหรือไม่
Nick Chammas

2
มันมีความหมายว่าเป็นการเพิ่มคำตอบของ @ Aaron มันเป็นเพียงมากที่จะแสดงความคิดเห็น
Kenneth Fisher

2

ฉันคิดว่ามันขึ้นอยู่กับ:

หากคำสั่งมาถึงเซิร์ฟเวอร์แล้วก่อนที่คุณจะถอดสายเคเบิลเครือข่ายคำสั่งจะยังคงทำงานตามปกติ

หากคุณมี TransactionScope (ใช้ใน. Net, ไม่แน่ใจว่าภาษาอื่น ๆ ) เพื่อแค็ปซูลคำสั่งการอัพเดททั้งหมดคุณสามารถหยุดการทำธุรกรรมที่จะกระทำได้ต่อเมื่อ transactionScope.Complete () ยังไม่ได้ดำเนินการ แต่ไม่มีการรับประกัน .. .


2
คุณกล่าวว่า "หากคำสั่งมาถึงเซิร์ฟเวอร์แล้วก่อนที่คุณจะถอดสายเคเบิลเครือข่ายคำสั่งจะยังคงทำงานตามปกติ" สิ่งนี้ขัดแย้งกับหน้า SQL Server BOL ที่ Martin เชื่อมโยงกับด้านบน ดู"ข้อผิดพลาดระหว่างการประมวลผลธุรกรรม"
Nick Chammas

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