ความล้มเหลวเดียวควรล้มเหลวในการดำเนินการเป็นกลุ่ม?


11

ใน API ฉันทำงานอยู่มีการดำเนินการลบจำนวนมากซึ่งยอมรับอาร์เรย์ของ ID:

["1000", ..., "2000"]

ฉันมีอิสระที่จะใช้การดำเนินการลบตามที่ฉันเห็นสมควรดังนั้นฉันตัดสินใจที่จะทำธุรกรรมทั้งหมด: นั่นคือถ้า ID เดียวไม่ถูกต้องคำขอทั้งหมดล้มเหลว ฉันจะเรียกสิ่งนี้ว่าโหมดเข้มงวด

try{
savepoint = conn.setSavepoint();

for(id : IDs)
    if( !deleteItem(id) ){
        conn.rollback(savepoint);
        sendHttp400AndBeDoneWithIt();
        return;
    }

conn.commit();
}

ทางเลือก (นำไปใช้ที่อื่นในชุดซอฟต์แวร์ของเรา) คือทำสิ่งที่เราทำได้ในแบ็กเอนด์และรายงานความล้มเหลวในอาเรย์ ส่วนหนึ่งของซอฟต์แวร์นั้นเกี่ยวข้องกับคำขอที่น้อยลงดังนั้นการตอบสนองจึงไม่ได้กลายเป็นอาร์เรย์ขนาดใหญ่ ... ในทางทฤษฎี


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

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


9
มันขึ้นอยู่กับ. ค่าใช้จ่ายในการมีบางสิ่งที่ไม่ถูกลบเมื่อมันควรจะเป็นคืออะไร? (ค่าใช้จ่ายถูกกำหนดเป็นข้อมูลที่ไม่ดี, ปวดหัว, พฤติกรรมที่ไม่พึงประสงค์, เวลาที่ผู้ดูแลระบบต้องแก้ไข ฯลฯ ) เป็นที่ยอมรับหรือไม่? หากคุณสามารถมีชีวิตอยู่กับผลที่ตามมาของการไม่ล้มเหลวทุกอย่างไปได้ ถ้ามันจะทำให้เกิดปัญหามากเกินไปอย่า คุณรู้จักซอฟต์แวร์และผลที่ตามมาดังนั้นคุณจะต้องทำการตัดสินใจ
Becuzz

1
@Becuzz ค่าใช้จ่ายจะเป็นผู้ใช้ที่สังเกตเห็นหนึ่งหรือสองที่เหลือและเปิดตั๋วเกี่ยวกับที่; สถานการณ์ปัจจุบันคือ "omg delete is broken" โชคดีที่ผู้ใช้เดินไปตามทางเดินดังนั้นจึงไม่เป็นปัญหามากเกินไปในครั้งนี้ ประเด็นก็คือผมชอบที่จะทำสิ่งที่ถูกต้องเมื่อใดก็ตามที่เป็นไปได้และมี codebase 10+ ปีพระเจ้าเท่านั้นที่รู้บางสิ่งบางอย่างสามารถยืนที่จะต้องทำอย่างถูกต้อง
ไทยรัฐ

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

1
@ imnota4 จุดยอดเยี่ยมที่ฉันไม่ได้พิจารณา UI จำกัด คำขอไม่เกิน 250 รายการ แต่ส่วนหลังไม่มีข้อ จำกัด ฉันขอให้คุณโพสต์ความคิดเห็นของคุณใหม่เป็นคำตอบได้ไหม
rath

1
โหมดที่ได้รับอนุญาตทำให้ผู้ดูแลระบบทำงานได้ง่ายขึ้นเพราะพวกเขาไม่จำเป็นต้องสร้างความล้มเหลวด้วยสแต็กของ id ทั้งหมด มันอาจเป็นประโยชน์เช่นกันในการแจ้งสาเหตุของข้อผิดพลาดแต่ละข้อ การค้นหาสาเหตุอาจเป็นไปได้ที่ผู้ใช้ขั้นสุดท้ายจะแก้ปัญหาโดยไม่มีตั๋ว "omg delete ถูกใช้งานไม่ได้"
Laiv

คำตอบ:


9

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

เรากำลังดำเนินการลบกับจุดสิ้นสุดนี้ ดูเหมือนDELETE /resource/bulk/หรือคล้ายกัน ฉันไม่จู้จี้จุกจิก สิ่งที่สำคัญที่นี่คือไม่ว่าคุณจะเข้มงวดหรือดีคุณต้องรายงานกลับสิ่งที่เกิดขึ้น

ตัวอย่างเช่น API ที่ฉันทำงานด้วยมีDELETE /v1/student/จุดปลายที่รับรหัสจำนวนมาก เราส่งคำขอเป็นประจำในระหว่างการทดสอบรับการ200ตอบกลับและคิดว่าทุกอย่างเรียบร้อยดีเท่านั้นที่จะค้นพบในภายหลังว่าทุกคนในรายการเป็นทั้งในฐานข้อมูลยัง (ตั้งค่าเป็นไม่ใช้งาน) หรือไม่ถูกลบจริงเนื่องจากข้อผิดพลาด ทำให้การโทรในอนาคตสับสนGET /v1/studentเพราะเราได้รับข้อมูลกลับมาซึ่งเราไม่ได้คาดหวัง

วิธีแก้ไขปัญหานี้มาในการอัปเดตในภายหลังซึ่งเพิ่มเนื้อหาลงในการตอบกลับด้วยรหัสที่ไม่ถูกลบ นี่คือ - สำหรับความรู้ของฉัน - เป็นแนวปฏิบัติที่ดีที่สุด

บรรทัดล่างไม่ว่าคุณจะทำอะไรตรวจสอบให้แน่ใจว่าคุณมีวิธีที่จะให้ผู้ใช้ทราบว่าเกิดอะไรขึ้นและอาจเป็นสาเหตุของมัน IE ถ้าเราเลือกรูปแบบที่เข้มงวดการตอบสนองอาจเป็น400 - DELETE failed on ID 1221 not foundไปได้ หากเราเลือกรุ่น 'ดี' อาจเป็นได้207 - {message:"failed, some ids not deleted", failedids:{1221, 23432, 1224}}(แก้ตัวการจัดรูปแบบ json ที่ไม่ดีของฉัน)

โชคดี!


6
207 Multi-Statusอาจจะเหมาะสมสำหรับการที่ตอบสนองความล้มเหลวบางส่วน
ริชาร์ดซ่า

1
เราจะไปที่นั่น! ฉันจำไม่ได้จริงๆ! ฉันจะไปข้างหน้าและอัปเดตคำตอบด้วยเพราะจริง ๆ แล้วมันเป็นไปตามมาตรฐาน
Adam Wells

2

หนึ่งควรจะเข้มงวดและอนุญาต

โดยปกติโหลดจำนวนมากจะถูกแบ่งออกเป็น 2 ขั้นตอน:

  • การตรวจสอบ
  • กำลังโหลด

ในระหว่างขั้นตอนการตรวจสอบความถูกต้องทุกระเบียนจะถูกตรวจสอบอย่างเคร่งครัดเพื่อให้แน่ใจว่าเป็นไปตามข้อกำหนดของข้อมูลจำเพาะ หนึ่งสามารถตรวจสอบ 10s จาก 1,000s ของบันทึกในเวลาเพียงไม่กี่วินาที ระเบียนที่ถูกต้องจะอยู่ในไฟล์ใหม่ที่จะโหลดหนึ่งรายการที่ไม่ถูกต้องจะถูกตั้งค่าสถานะและลบออกและมักจะใส่ในไฟล์แยกต่างหาก (ไฟล์ข้าม) จากนั้นระบบจะส่งการแจ้งเตือนไปยังระเบียนที่ไม่ผ่านการตรวจสอบเพื่อให้สามารถตรวจสอบและวินิจฉัยเพื่อแก้ไขปัญหา

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


ฉันไม่ตรวจสอบความถูกต้องของ ID กับค่า DB ฉันเพียงแค่พยายามลบพวกเขาและดูว่ามันจะไปอย่างไรหรือมันจะใช้เวลาตลอดไป การยกเลิกหลังจากความล้มเหลวของ N ดูเหมือนจะเป็นคำแนะนำที่สมเหตุสมผลมาก +1
rath

2

ความล้มเหลวเดียวควรล้มเหลวในการดำเนินการเป็นกลุ่ม?

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

คำถามที่ 1 : 'ผู้ใช้จะเกิดอะไรขึ้นหากการลบแต่ละรายการล้มเหลว'

คำตอบควรขับเคลื่อนส่วนที่เหลือของพฤติกรรมการออกแบบ / การใช้งาน

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

หากการลบที่ล้มเหลวจำเป็นต้องได้รับการแก้ไขก่อนที่ผู้ใช้จะสามารถดำเนินการต่อได้แสดงว่าเข้มงวดกว่า

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

คำถามที่ 2 : 'จะมีปัญหาการเชื่อมโยงข้อมูล / ความสอดคล้องใด ๆ หรือไม่หากงานที่ตามมาจะดำเนินการกับรายการที่ไม่ถูกลบยังอยู่ในแหล่งข้อมูลหรือไม่'

อีกครั้งคำตอบจะผลักดันการออกแบบ / พฤติกรรมที่ดีที่สุด ใช่ -> เข้มงวด, ไม่ -> อนุญาต, อาจ -> เข้มงวดหรือเลือกผู้ใช้ (โดยเฉพาะถ้าผู้ใช้สามารถขึ้นอยู่กับการกำหนดผลที่ถูกต้อง)


0

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


-1

ฉันจะบอกว่าจุดสำคัญจุดหนึ่งที่นี่คือความหมายสำหรับการลบข้อมูลจำนวนมาก

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

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

ดังที่คำตอบอื่น ๆ ระบุไว้: ไม่ว่าในกรณีใด ๆ จะบอกผู้ใช้ว่า "เกิดอะไรขึ้น"

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