ปัญหาที่มักพบเจอบ่อยมาก ๆ ของระบบงานคือ
การแย่งใช้งาน resource ต่าง ๆ ที่มีจำกัด พร้อมกัน
ผลที่ตามมาคือ ระบบงานทำงานไม่ถูกต้อง
เช่น เกิดการทำงานซ้ำ เป็นต้น
หรือเราจะเรียกว่า race condition

ว่าแต่ถ้าเกิดปัญหาแบบนี้ เราจะแก้ไขอย่างไรดี ?

ก่อนอื่นก็ต้องไปดูที่ use case และต้นเหตุของปัญหาก่อน
เพื่อที่จะแก้ไขได้ตรงจุดมากยิ่งขึ้น

การทำงานช้า ทำให้ฝั่ง UI รอนาน หรือ กดซ้ำได้

ผลที่ตามมาคือ เกิดการ submit ข้อมูลมาซ้ำได้
ส่วนใหญ่ก็แก้ไขด้วย ให้ทางฝั่ง UI ไม่ให้กดซ้ำนั่นเอง
เพราะว่า ง่ายสุด ๆ
คำถามคือ ปัญหาลดลงไหม ถ้าลดถือว่า ok นะ
แต่มันแก้ไขได้หมดไหม ?
ตรงนี้น่าคิด

ทางฝั่ง Backend ต้องแก้ไขไหม ?

เช่น ต้องทำงานแบบ idempotence ไหม ?
คือ ถ้าเป็น request เหมือนกันหรือตัวเดิม จะไม่ทำซ้ำ

เช่น ต้องให้ทำงานได้เร็วขึ้น
ด้วยการเปลี่ยน logic การทำงาน
หรือ scale ในส่วนการทำงานต่าง ๆ เพื่อรองรับ

หรือต้องเอาระบบ Queue หรือ First-In First-Out มาช่วยจัดการ
เพื่อการันตีการทำงานครั้งเดียวแน่ ๆ ไม่ซ้ำ

หรือจะเอาแนวคิดเรื่องของการจองมาใช้งานดี ? (Reservation pattern)

ขั้นตอนการทำงานก็ไม่ยากไม่ง่าย
แต่เพิ่มขั้นตอนการทำงานมาหน่อย ดังนี้

จากเดิมก่อนจะใช้งาน เช่น การใช้งานระบบส่วนลด
จะต้องทำการตรวจสอบว่า สามารถใช้งานได้หรือไม่
โดยปกติตอนที่เราทดสอบเพียงคนเดียว ก็ผ่านตลอด
แต่เมื่อ deploy ขึ้น production แล้ว
จะพบว่า ทำไมมีปัญหาทุกครั้ง
เช่น ทำไมมีคนใช้ promotion เกินกว่าที่กำหนดนะ !!

แน่นอนว่า ก็ให้เกิดปัญหาและคำถามตามมาเยอะแน่ ๆ
ดังนั้นลองมาปรับเปลี่ยนขั้นตอนการทำงาน และ วิธีคิดหน่อยสิ

ก่อนที่จะใช้งานใด ๆ ก็ตาม จะให้ทำการจองก่อน (Reservation)

ดังนั้นจึงต้องมีการกำหนด status ของการใช้งาน เช่น

  • จอง
  • ใช้งานสำเร็จ
  • ใช้งานไม่สำเร็จ

โดยในการจองก่อนใช้งาน จะมีเวลากำหนดให้ด้วยเช่น 5-10 นาทีเป็นต้น
แล้วแต่จะกำหนดให้เข้ากับการใช้งาน

ดังนั้นก่อนจะใช้งานจะได้ id หรือ code หรือ token ของการจองก่อน
จากนั้นให้ทำการส่งสิ่งที่ได้มาด้วย ตอนการใช้งานส่วนลด
จะช่วยให้เราตรวจสอบ race condition ได้ง่าย
ถ้าใครใช้งาน โดยไม่มีการจอง ก็ reject ไป
หรือถ้าใช้งาน โดยที่การจองหมดอายุ ก็ reject ไป

ทำให้เราสามารถแยกการทำงานหรือพัฒนาระบบเป็น 2 ขั้นตอนได้เลย
ทำให้เราสามารถ scale ระบบงานได้ตามส่วนงานได้ง่ายขึ้นอีก

แน่นอนว่า มีข้อดี ย่อมมีข้อเสียเสมอ

อย่าง database สำหรับการจอง สามารถเป็น database ต่างจากระบบส่วนลดได้อีก
เพราะว่าการจองต้องเร็ว !!
ส่วน process การใช้ส่วนลดสามารถช้าได้ เพราะว่าต้องการความถูกต้องมาก

แต่สิ่งที่ต้องทำตามมาคือ ช่วงเวลาหมดอายุต้องมีการตรวจสอบ
ซึ่งแน่นอนว่า มีการงอก หรืองาน เพิ่มมาแน่นอน
ตรงนี้ทำให้ระบบงานมีความซับซ้อนมากขึ้น
ต้องคิดว่า มันคุ้มกับสิ่งที่ได้รับมาหรือไม่

ลองคิดดูสิว่า
ถ้าเก็บลงใน RDBMS จะทำการตรวจสอบอย่างไร ?
ต้องมี batch process ที่ต้องมีลบ หรือ update ข้อมูลทุก xx นาทีไหม ?
แต่ถ้าใช้ database ที่จัดการเรื่องนี้ให้เองจะดีกว่าไหม ?
สิ่งต่าง ๆ เหล่านี้ เราต้องเลือกให้เหมาะสม
ทั้ง skill และ business ด้วยเสมอ

สุดท้าย ถ้าเราเจอปัญหาแบบนี้ จะแก้ไขกันอย่างไรบ้าง ?