#backend#adr#query-gateway#transaction
ADR-0009 write batch commit แบบ atomic
สถานะ: accepted (ตรงกับโค้ด) แต่ตัวเลข "ใช้เพดานเท่าอ่านที่ 20" ใน ADR ล้าสมัย — โค้ดปัจจุบันแยกเพดานฝั่งเขียนเป็น MaxExecBatchStatements = 1000 และ MaxExecBatchBytes = 2 << 20 (2 MB) (domain/query/query.go:77,81).
ทำงานอย่างไร
POST /query/execBatchตรวจทุก statement ล่วงหน้าด้วยNewWriteBatchStatements(query.go:397) — ได้ErrNoStatements/ErrTooManyExecStatements/ErrExecBatchTooLarge.Gateway.ExecBatchเปิดpool.Beginแล้วรันตามลำดับด้วยQueryExecModeSimpleProtocolเก็บRowsAffectedต่อ statement จากนั้นCommit(dynamicsql/gateway.go:197-235).- statement ใดพัง (validation หรือ execution) → rollback ทั้งชุดและ error ระบุ index ของ statement (
gateway.go:192-196). - การเริ่ม/จบ transaction อยู่ใน
dynamicsql.Gatewayทั้งหมด ไม่ส่ง tx handle ขึ้นไปยังapplication/query.Service(...0009...md:7,12) ใช้ timeout 30 วินาทีรวมทั้งชุด (application/query/service.go:153).
ตัวเลือกที่ไม่เลือก
- ใช้โมเดลเดียวกับ read batch (หยุดที่ตัวที่พัง ไม่ rollback): เขียนครึ่ง ๆ กลาง ๆ จะค้างใน DB บริษัท.
- เปิด
Begin/Commit/RollbackบนQueryGateway: รั่ว tx ของ pgx ขึ้น application layer และ test double. - ใช้ค่าเดียวกับ
MaxBatchStatements: สองเพดานคุมคนละเรื่อง (พื้นที่ validate vs ระยะเวลา lock).
ข้อควรระวัง
- write batch ถือ row lock ตลอด transaction — ชุดใหญ่/ช้าเสี่ยง lock contention กับ session อื่น (
...0009...md:16). - ระวังตัวเลข:
peekJSONของ middleware สิทธิ์อ่าน body ได้ 1 MB เพื่อเดาสิทธิ์ ขณะที่เพดาน batch คือ 2 MB (ยังไม่ยืนยันผลข้างเคียง) — ดู สิทธิ์เมนูและ middleware RequireRight (Menu rights / permission). - ตอนนี้ทุก statement ยังต้องผ่านนโยบายเขียนของ browser (ADR-0011 ล็อก SQL เขียนจาก browser: ตารางเงิน/สต๊อก/GL ผ่าน /api/process เท่านั้น).
ที่มาในโค้ด
backend/internal/domain/query/query.go:77—MaxExecBatchStatements;:81—MaxExecBatchBytes;:397—NewWriteBatchStatements.backend/internal/adapter/outbound/dynamicsql/gateway.go:197—ExecBatch.backend/internal/application/query/service.go:153— timeout ครอบทั้งชุด.backend/docs/adr/0009-query-exec-batch-transactional.md:7— เหตุผลการตัดสินใจ.
ดูเพิ่ม
Query Gateway: /query/list, limit, batch, exec, execBatch · ADR-0008 /query/batch รัน SELECT หลายตัวในคำขอเดียว · ADR-0011 ล็อก SQL เขียนจาก browser: ตารางเงิน/สต๊อก/GL ผ่าน /api/process เท่านั้น · สารบัญ ADR ของ backend (Architecture Decision Records)