ข้ามไปเนื้อหาหลัก

ระบบบัญชีดิจิทัลอาจสูญเสียเงินเงียบๆ แม้เทสต์ผ่านฉลุย

นักพัฒนาเผยปัญหาเรซคอนดิชันในระบบชำระเงินที่การเขียนเทสต์ทั่วไปไม่พบ พร้อมเปิดตัว repository โอเพนซอร์สจำลองช่องโหว่

เรียบเรียงโดย AI
Inewgen
25 Sep 2026ที่มา: Dev.to2 นาทีอ่าน (0 ครั้ง)
แชร์
ระบบบัญชีดิจิทัลอาจสูญเสียเงินเงียบๆ แม้เทสต์ผ่านฉลุย

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

ขนาดตัวอักษร
  • ข้อผิดพลาดทางการเงินส่วนใหญ่ไม่ได้เกิดจากสูตรคำนวณแต่มาจากปัญหา Concurrency
  • การอ่านและเขียนข้อมูลพร้อมกันทำให้ยอดเงินสูญหายโดยไม่มีการแจ้งเตือนในระบบ CRUD
  • ที่เก็บข้อมูล ledger-core บน GitHub ช่วยจำลองปัญหาเหล่านี้ด้วย 3 กลยุทธ์การจัดการ
  • การบังคับใช้ความถูกต้องในตัวสร้างและการใช้หน่วยย่อยที่เป็นจำนวนเต็มช่วยป้องกันข้อผิดพลาด

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

การทำงานร่วมกับระบบธุรกรรมและการชำระเงินเผยให้เห็นว่า ความผิดพลาดลักษณะนี้มีความเงียบเชียบในการแสดงผล ข้อผิดพลาดประเภท Null Reference จะโยนข้อยกเว้นออกมาทันที และสูตรที่ผิดจะปรากฏตั้งแต่การทดสอบรอบแรก ทว่าการอัปเดตที่สูญหายกลับทำให้ตัวเลขผิดเพี้ยนไปเล็กน้อยในบัญชีเดียวและวันเดียว จนกว่ากระบวนการกระทบยอดจะทำงานและพบว่าเงินจำนวนสี่ร้อยดอลลาร์หายไปไหน

database server rack data center

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง

เพื่อทำให้ความล้มเหลวดังกล่าวปรากฏชัดเจน จึงมีการพัฒนาที่เก็บข้อมูลขนาดเล็กชื่อ ledger-core บน GitHub ซึ่งเป็นระบบบัญชีแบบบันทึกรายการคู่ที่มีกลยุทธ์การจัดการการทำงานพร้อมกันสามรูปแบบภายใตกินเตอร์เฟซเดียว พร้อมชุดการทดสอบที่พิสูจน์ว่ากลยุทธ์ใดรักษาเงินไว้ได้และกลยุทธ์ใดทำเงินหาย

ปัญหา Race Condition ในระบบการเงินเป็นหนึ่งในภัยเงียบที่น่ากลัวที่สุดสำหรับนักพัฒนา เนื่องจากระบบอัตโนมัติในปัจจุบันมักรันเธรดคู่ขนานจำนวนมากเพื่อรองรับปริมาณธุรกรรมที่สูง การพึ่งพา Unit Test แบบดั้งเดิมจึงไม่เพียงพอ เพราะการทดสอบส่วนใหญ่มักรันแบบซิงโครนัสหรือจำลองสถานการณ์การชนกันของข้อมูลได้ไม่ดีพอ นักพัฒนาจึงต้องออกแบบกลยุทธ์การล็อกข้อมูลหรือใช้กลไก Concurrency Control ที่รัดกุมตั้งแต่ระดับสถาปัตยกรรม

กฎเหล็กเพียงข้อเดียวของระบบบัญชีคือ ผลรวมของยอดคงเหลือทั้งหมดหลังจากทำธุรกรรม N รายการต้องเท่ากับผลรวมก่อนหน้า ธุรกรรมมีหน้าที่ย้ายเงินเท่านั้น โดยจะไม่สร้างหรือทำลายเงินขึ้นมาใหม่

ไม่อยากพลาดข่าวใหม่?

สมัครรับสรุปข่าวสารใหม่ทางอีเมล ไม่บ่อยจนรำคาญ

โฆษณา

3กลยุทธ์การจัดการ Concurrency

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

"That SpinWait is the honest part. The window exists in real code too. It is just narrower, which means you hit it on a Tuesday in production instead of every time in CI."

ผู้พัฒนา ledger-core

ที่มา: Dev.to

ความคิดเห็น

แสดงความคิดเห็น
0/2000

พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้