The 5 Seconds Problem
อัพเดทล่าสุด: 19 ม.ค. 2025
1 ผู้เข้าชม
เวลา 5 วินาที ของเรานานเท่ากันหรือไม่
การรับรู้เวลาที่ยาวสั้นไม่เท่ากัน ทำให้ความหมายของคำอธิบายเหตุการณ์ที่เกิดขึ้นเวลาเดียวกัน หรือ เกิดขึ้นพร้อมกัน ไม่เป็นอย่างที่เราเข้าใจ ชั่วพริบตาที่ดูว่าเป็นเวลาเดียวกัน หากนำมาฉายภาพแบบสโลโมชั่น จะเห็นลำดับของเหตุการณ์ย่อย ๆ ก่อนที่จะเป็นผลลัพธ์ ทำให้เข้าใจที่มาที่ไปได้
สัปดาห์ที่แล้ว ผู้ใช้แจ้งปัญหามาว่า มีออเดอร์ของสินค้าที่ไม่มีในสต็อกหลุดมาให้สโตร์จัดของอีกแล้ว ก่อนหน้านั้นเคยมีเคสเช่นนี้เกิดขึ้นประปราย แต่การจำลองเหตุการณ์เพื่อหาสาเหตุทำได้ยาก เพราะเมื่อเวลาผ่านไปยอดสต็อกเปลี่ยนแปลงไปแล้ว
เอกสารที่เกี่ยวข้องของกระบวนการนี้ ประกอบด้วย OF และ DL เมื่อทีมขายแจ้งออเดอร์เข้ามา แผนก Order Processing จะบันทึกรายการเป็น OF ใบรับคำสั่งซื้อก่อน ขั้นตอนนี้มีการตรวจวงเงินและยอดค้างชำระของลูกค้า หากไม่พอจะต้องรออนุมัติการขาย เมื่อผ่านขั้นตอนนี้แล้วจะเปิด DL ใบสั่งจัดสินค้า ที่ส่งรายการมาจาก OF ไม่ต้องคีย์ข้อมูลใหม่ มีการตรวจยอดสต็อก หากมีรายการไหนไม่พอไม่ยอมให้ยืนยันบันทึก ต้องเช็คเงื่อนไขว่าเอายังไง ยังไม่ต้องส่งทั้งบิล หรือเอารายการนั้นออกแล้วค้างเป็น Back Order จัดส่งเฉพาะที่มีของ
ข้อสันนิษฐานหนึ่งที่อาจเกิดขึ้นได้ ช่วงเวลาเร่งด่วนมีผู้เปิด DL สั่งจัดสินค้าหลายคน ถ้าเป็นสินค้าเดียวกันตอนที่เช็คยอดคงเหลือก็มีพอ ต่างคนต่างบันทึกพร้อมกัน กลายเป็นว่าไม่รู้ว่าอีกคนก็แย่งสั่งสินค้าตัวเดียว
กรณีนี้คำว่า "บันทึกพร้อมกัน" ไม่ได้หมายถึงเวลา ณ จุดเดียวกัน แต่เป็นช่วงเวลาที่มีเวลาเดียวกันเหลื่อมซ้อนกันอยู่ ยิ่งใช้เวลาตั้งแต่เช็คยอดสต็อกจนกว่าจะบันทึกเป็นใบสั่งจัดสินค้านานเท่าไหร่ ก็ยิ่งมีโอกาสเกิดปัญหา
เมื่อผู้ใช้คนที่หนึ่งกำลังเปิดใบสั่งจัดสินค้า จะต้องใช้เวลาในการอินพุทข้อมูลต่าง ๆ รวมทั้งรายการสินค้า ระหว่างนั้นโปรแกรมจะตรวจสอบสต็อกคงเหลือตามที่ป้อนเข้าไปทีละรายการ สมมติว่าเป็นสินค้า A บังเอิญว่าเหลือ 1 ชิ้นพอดี
ในเวลาไล่เลี่ยกันผู้ใช้คนที่สองก็เปิดใบสั่งจัดสินค้าให้ลูกค้าอีกราย ขณะที่คนแรกยังไม่ได้บันทึกตัดสต็อกเพราะมีสินค้าอื่นที่อีกหลายรายการ บังเอิญคนที่สองก็มีสั่งสินค้า A ตอนนั้นยังเช็คได้ว่าสต็อกยังเหลืออยู่เช่นกัน กลายเป็นว่าทั้งสองคนสามารถบันทึกเพราะเข้าใจว่าสินค้า 1 ชิ้นนั้นเป็นของตน
หากจะออกแบบให้รัดกุมกว่านี้ ก่อนที่จะบันทึกข้อมูลโปรแกรมควรตรวจยอดคงเหลือสินค้าทุกรายการล่าสุดอีกครั้ง แต่ผมเลือกไม่ทำเช่นนั้น เพราะไม่คุ้ม เป็นการเพิ่มภาระให้กับเซิร์ฟเวอร์ และเกิดการหน่วงเวลาในจังหวะบันทึกข้อมูล เมื่อคำนวณปัจจัยที่จะทำให้เกิดเหตุการณ์แย่งสินค้ากัน นอกจากต้องเป็นสินค้าเดียวกันแล้ว ต้องมีสต็อกเหลือจำนวนไม่มากด้วย แล้วต้องบังเอิญมีใบสั่งที่รายการเยอะใช้เวลานาน
แต่ครั้งล่าสุดเป็นการทำงานในช่วงวันหยุด ตรวจสอบจากบันทึกย้อนหลัง ปรากฏว่าช่วงเวลานั้นไม่มีคนอื่นทำงานพร้อมกัน แต่ก็ยังเกิดปัญหาสั่งจัดสินค้าที่ไม่มีในสต็อกได้อีก ดูเหมือนว่าโปรแกรมจะทำงานผิดพลาด
เมื่อเอาใบสั่งที่มีปัญหานั้นมาจำลองเหตุการณ์ น้องในทีมสังเกตเห็นว่าระหว่างที่เปิดใบสั่งสินค้านั้น มีช่วงจังหวะเวลาสั้น ๆ ที่ปุ่ม Save แสดงขึ้นมา ก่อนที่หายไปพร้อมกับโปรแกรมฟ้องว่าสินค้าไม่พอ เป็นไปได้หรือไม่ที่เกิดจากผู้ใช้กดปุ่มนั้นได้ก่อนที่จะหาย
พอได้เงื่อนงำแล้ว ผมจึงหาทางทดสอบอย่างละเอียดเพื่อตอบคำถามสองข้อ ข้อแรกทำไมใบสั่งสินค้านี้จึงมีปุ่ม Save แสดงขึ้นมาแล้วค่อยหายไป และข้อสองมีโอกาสแค่ไหนที่ผู้ใช้กดปุ่ม Save นี้ทัน
การทดสอบต้องทำกับใบสั่งจัดสินค้าที่มีปัญหาใบนั้น จึงพบสาเหตุที่มาจาก 3 ปัจจัยร่วมกัน
เกิดจากจำนวนรายการสินค้า (ทั้งหมด 13 รายการ)
สินค้าที่ไม่มีสต็อกอยู่ในรายการที่ 9
โปรแกรมออกแบบไม่รัดกุม
เมื่อผู้ใช้ส่งต่อข้อมูลจากใบรับคำสั่งซื้อมาสั่งจัดสินค้าให้สโตร์ ไม่ช้าอย่างที่คิด เป็นกระบวนการที่ไม่ต้องคีย์ข้อมูลใหม่ทีละบรรทัด แต่รายการทั้งหมดจะถูกคัดลอกมารวดเดียวเป็นใบสั่งจัด แล้วรอให้สั่งบันทึก ไม่ตรงกับสมมติฐาน บันทึกพร้อมกัน ที่คิดว่าใช้เวลานานในการอินพุทข้อมูล แต่กลับเป็นเพราะผู้ใช้เร็วเกินไป จนโปรแกรมที่ใช้เวลาเช็คยอดสต็อกเริ่มจากสินค้ารายการแรกทำงานไม่ทัน บังเอิญว่าบิลใบนี้สินค้ารายการที่ 9 ไม่มีสต็อก ระหว่างที่ตรวจรายการ 18 ยังไม่พบปัญหา โปรแกรมแสดงปุ่ม Save ตามปกติ เท่ากับว่ามีเวลาเกือบ 5 วินาที นานพอที่ผู้ใช้จะกดปุ่ม Save ได้ก่อนตรวจสต็อกครบ
จะเรียกว่าเป็นความผิดพลาดของโปรแกรมก็ได้ ที่กำหนดสถานะเริ่มต้นของการตรวจสต็อกว่าเป็นปกติ แต่จริง ๆ แล้วยังตรวจไม่ครบ ควรเริ่มต้นด้วยการซ่อนปุ่ม Save ไว้ก่อน รอจนกว่าจะตรวจสต็อกครบทุกรายการแล้วค่อยแสดง
บทเรียนของ 5 วินาที เวลาสั้น ๆ แต่สำหรับผู้ใช้ที่ชำนาญ เป็นเวลาที่มากพอที่จะทำอะไรได้หลายอย่าง นานพอที่เปิดโอกาสให้เกิดความผิดพลาดในระบบงาน
ครั้งนี้เป็นการคลี่คลาย bug ของโปรแกรมที่ผมประทับใจ อาศัยความช่างสังเกตของทีมงาน ต้องจำลองเหตุการณ์ด้วยข้อมูลตามเงื่อนไขเฉพาะ แล้วประเมินความเป็นไปได้ของจังหวะเวลาเพียงชั่วแว๊บเดียวกับปฏิกริยาของผู้ใช้
การรับรู้เวลาที่ยาวสั้นไม่เท่ากัน ทำให้ความหมายของคำอธิบายเหตุการณ์ที่เกิดขึ้นเวลาเดียวกัน หรือ เกิดขึ้นพร้อมกัน ไม่เป็นอย่างที่เราเข้าใจ ชั่วพริบตาที่ดูว่าเป็นเวลาเดียวกัน หากนำมาฉายภาพแบบสโลโมชั่น จะเห็นลำดับของเหตุการณ์ย่อย ๆ ก่อนที่จะเป็นผลลัพธ์ ทำให้เข้าใจที่มาที่ไปได้
สัปดาห์ที่แล้ว ผู้ใช้แจ้งปัญหามาว่า มีออเดอร์ของสินค้าที่ไม่มีในสต็อกหลุดมาให้สโตร์จัดของอีกแล้ว ก่อนหน้านั้นเคยมีเคสเช่นนี้เกิดขึ้นประปราย แต่การจำลองเหตุการณ์เพื่อหาสาเหตุทำได้ยาก เพราะเมื่อเวลาผ่านไปยอดสต็อกเปลี่ยนแปลงไปแล้ว
เอกสารที่เกี่ยวข้องของกระบวนการนี้ ประกอบด้วย OF และ DL เมื่อทีมขายแจ้งออเดอร์เข้ามา แผนก Order Processing จะบันทึกรายการเป็น OF ใบรับคำสั่งซื้อก่อน ขั้นตอนนี้มีการตรวจวงเงินและยอดค้างชำระของลูกค้า หากไม่พอจะต้องรออนุมัติการขาย เมื่อผ่านขั้นตอนนี้แล้วจะเปิด DL ใบสั่งจัดสินค้า ที่ส่งรายการมาจาก OF ไม่ต้องคีย์ข้อมูลใหม่ มีการตรวจยอดสต็อก หากมีรายการไหนไม่พอไม่ยอมให้ยืนยันบันทึก ต้องเช็คเงื่อนไขว่าเอายังไง ยังไม่ต้องส่งทั้งบิล หรือเอารายการนั้นออกแล้วค้างเป็น Back Order จัดส่งเฉพาะที่มีของ
ข้อสันนิษฐานหนึ่งที่อาจเกิดขึ้นได้ ช่วงเวลาเร่งด่วนมีผู้เปิด DL สั่งจัดสินค้าหลายคน ถ้าเป็นสินค้าเดียวกันตอนที่เช็คยอดคงเหลือก็มีพอ ต่างคนต่างบันทึกพร้อมกัน กลายเป็นว่าไม่รู้ว่าอีกคนก็แย่งสั่งสินค้าตัวเดียว
กรณีนี้คำว่า "บันทึกพร้อมกัน" ไม่ได้หมายถึงเวลา ณ จุดเดียวกัน แต่เป็นช่วงเวลาที่มีเวลาเดียวกันเหลื่อมซ้อนกันอยู่ ยิ่งใช้เวลาตั้งแต่เช็คยอดสต็อกจนกว่าจะบันทึกเป็นใบสั่งจัดสินค้านานเท่าไหร่ ก็ยิ่งมีโอกาสเกิดปัญหา
เมื่อผู้ใช้คนที่หนึ่งกำลังเปิดใบสั่งจัดสินค้า จะต้องใช้เวลาในการอินพุทข้อมูลต่าง ๆ รวมทั้งรายการสินค้า ระหว่างนั้นโปรแกรมจะตรวจสอบสต็อกคงเหลือตามที่ป้อนเข้าไปทีละรายการ สมมติว่าเป็นสินค้า A บังเอิญว่าเหลือ 1 ชิ้นพอดี
ในเวลาไล่เลี่ยกันผู้ใช้คนที่สองก็เปิดใบสั่งจัดสินค้าให้ลูกค้าอีกราย ขณะที่คนแรกยังไม่ได้บันทึกตัดสต็อกเพราะมีสินค้าอื่นที่อีกหลายรายการ บังเอิญคนที่สองก็มีสั่งสินค้า A ตอนนั้นยังเช็คได้ว่าสต็อกยังเหลืออยู่เช่นกัน กลายเป็นว่าทั้งสองคนสามารถบันทึกเพราะเข้าใจว่าสินค้า 1 ชิ้นนั้นเป็นของตน
หากจะออกแบบให้รัดกุมกว่านี้ ก่อนที่จะบันทึกข้อมูลโปรแกรมควรตรวจยอดคงเหลือสินค้าทุกรายการล่าสุดอีกครั้ง แต่ผมเลือกไม่ทำเช่นนั้น เพราะไม่คุ้ม เป็นการเพิ่มภาระให้กับเซิร์ฟเวอร์ และเกิดการหน่วงเวลาในจังหวะบันทึกข้อมูล เมื่อคำนวณปัจจัยที่จะทำให้เกิดเหตุการณ์แย่งสินค้ากัน นอกจากต้องเป็นสินค้าเดียวกันแล้ว ต้องมีสต็อกเหลือจำนวนไม่มากด้วย แล้วต้องบังเอิญมีใบสั่งที่รายการเยอะใช้เวลานาน
แต่ครั้งล่าสุดเป็นการทำงานในช่วงวันหยุด ตรวจสอบจากบันทึกย้อนหลัง ปรากฏว่าช่วงเวลานั้นไม่มีคนอื่นทำงานพร้อมกัน แต่ก็ยังเกิดปัญหาสั่งจัดสินค้าที่ไม่มีในสต็อกได้อีก ดูเหมือนว่าโปรแกรมจะทำงานผิดพลาด
เมื่อเอาใบสั่งที่มีปัญหานั้นมาจำลองเหตุการณ์ น้องในทีมสังเกตเห็นว่าระหว่างที่เปิดใบสั่งสินค้านั้น มีช่วงจังหวะเวลาสั้น ๆ ที่ปุ่ม Save แสดงขึ้นมา ก่อนที่หายไปพร้อมกับโปรแกรมฟ้องว่าสินค้าไม่พอ เป็นไปได้หรือไม่ที่เกิดจากผู้ใช้กดปุ่มนั้นได้ก่อนที่จะหาย
พอได้เงื่อนงำแล้ว ผมจึงหาทางทดสอบอย่างละเอียดเพื่อตอบคำถามสองข้อ ข้อแรกทำไมใบสั่งสินค้านี้จึงมีปุ่ม Save แสดงขึ้นมาแล้วค่อยหายไป และข้อสองมีโอกาสแค่ไหนที่ผู้ใช้กดปุ่ม Save นี้ทัน
การทดสอบต้องทำกับใบสั่งจัดสินค้าที่มีปัญหาใบนั้น จึงพบสาเหตุที่มาจาก 3 ปัจจัยร่วมกัน
เกิดจากจำนวนรายการสินค้า (ทั้งหมด 13 รายการ)
สินค้าที่ไม่มีสต็อกอยู่ในรายการที่ 9
โปรแกรมออกแบบไม่รัดกุม
เมื่อผู้ใช้ส่งต่อข้อมูลจากใบรับคำสั่งซื้อมาสั่งจัดสินค้าให้สโตร์ ไม่ช้าอย่างที่คิด เป็นกระบวนการที่ไม่ต้องคีย์ข้อมูลใหม่ทีละบรรทัด แต่รายการทั้งหมดจะถูกคัดลอกมารวดเดียวเป็นใบสั่งจัด แล้วรอให้สั่งบันทึก ไม่ตรงกับสมมติฐาน บันทึกพร้อมกัน ที่คิดว่าใช้เวลานานในการอินพุทข้อมูล แต่กลับเป็นเพราะผู้ใช้เร็วเกินไป จนโปรแกรมที่ใช้เวลาเช็คยอดสต็อกเริ่มจากสินค้ารายการแรกทำงานไม่ทัน บังเอิญว่าบิลใบนี้สินค้ารายการที่ 9 ไม่มีสต็อก ระหว่างที่ตรวจรายการ 18 ยังไม่พบปัญหา โปรแกรมแสดงปุ่ม Save ตามปกติ เท่ากับว่ามีเวลาเกือบ 5 วินาที นานพอที่ผู้ใช้จะกดปุ่ม Save ได้ก่อนตรวจสต็อกครบ
จะเรียกว่าเป็นความผิดพลาดของโปรแกรมก็ได้ ที่กำหนดสถานะเริ่มต้นของการตรวจสต็อกว่าเป็นปกติ แต่จริง ๆ แล้วยังตรวจไม่ครบ ควรเริ่มต้นด้วยการซ่อนปุ่ม Save ไว้ก่อน รอจนกว่าจะตรวจสต็อกครบทุกรายการแล้วค่อยแสดง
บทเรียนของ 5 วินาที เวลาสั้น ๆ แต่สำหรับผู้ใช้ที่ชำนาญ เป็นเวลาที่มากพอที่จะทำอะไรได้หลายอย่าง นานพอที่เปิดโอกาสให้เกิดความผิดพลาดในระบบงาน
ครั้งนี้เป็นการคลี่คลาย bug ของโปรแกรมที่ผมประทับใจ อาศัยความช่างสังเกตของทีมงาน ต้องจำลองเหตุการณ์ด้วยข้อมูลตามเงื่อนไขเฉพาะ แล้วประเมินความเป็นไปได้ของจังหวะเวลาเพียงชั่วแว๊บเดียวกับปฏิกริยาของผู้ใช้
บทความที่เกี่ยวข้อง