FiveM MariaDB Transaction Isolation Level คืออะไร? READ COMMITTED, REPEATABLE READ และ SERIALIZABLE ต่างกันอย่างไร
FiveM Transaction Isolation Level คือระดับที่กำหนดว่า Transaction หนึ่งสามารถมองเห็นการเปลี่ยนแปลงข้อมูลจาก Transaction อื่นได้มากน้อยเพียงใด รวมถึงมีผลต่อ Snapshot, Locking และพฤติกรรมเมื่อหลาย FiveM Resources อ่านหรือแก้ Database พร้อมกัน
MariaDB รองรับ Isolation Level หลัก 4 ระดับ ได้แก่ READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ และ SERIALIZABLE ขณะที่ oxmysql มี ConVar mysql_transaction_isolation_level สำหรับกำหนด Isolation Level ของ Transaction โดยใช้ค่าตั้งแต่ 1–4 และ ค่า Default ของ oxmysql คือ 2 = READ COMMITTED.
นี่เป็นจุดที่ต้องแยกให้ออก เพราะ MariaDB/InnoDB โดยทั่วไปใช้ REPEATABLE READ เป็น Default Isolation Level แต่ MySQL.transaction ของ oxmysql มีค่า Default ของ ConVar เป็น READ COMMITTED.
จำง่ายๆ:
oxmysql mysql_transaction_isolation_level
1 = REPEATABLE READ
2 = READ COMMITTED ← oxmysql default
3 = READ UNCOMMITTED
4 = SERIALIZABLE
① Transaction Isolation Level คืออะไร
สมมติ Player A และ Player B กำลังใช้ข้อมูลเดียวกัน:
Transaction A
↓
อ่าน / แก้ข้อมูล
พร้อมกับ
Transaction B
↓
อ่าน / แก้ข้อมูลเดียวกัน
Isolation Level เป็นกฎที่กำหนดว่า:
A จะเห็นข้อมูลของ B เมื่อไร
B จะเห็นข้อมูลของ A เมื่อไร
Snapshot จะเปลี่ยนหรือไม่
การอ่านต้อง Lock เพิ่มหรือไม่
ระดับที่สูงขึ้นไม่ได้หมายความว่า “ดีกว่าเสมอ”
เพราะโดยทั่วไปต้องแลกกับ:
Consistency
↔
Concurrency
↔
Locking
↔
Performance
② oxmysql Transaction ทำงานอย่างไร
oxmysql ระบุว่า MySQL.transaction จะ Execute หลาย Queries และ Commit เฉพาะเมื่อ Queries ทั้งหมดสำเร็จ ถ้ามี Query ใดล้มเหลว Queries ใน Transaction นั้นจะไม่ถูก Commit และ Function คืนค่าเป็น Boolean เพื่อบอกผลของ Transaction.
ตัวอย่าง:
local success = MySQL.transaction.await({
{
query = [[
UPDATE `player_profiles`
SET `status` = ?
WHERE `id` = ?
]],
values = {
'active',
profileId
}
},
{
query = [[
UPDATE `player_settings`
SET `updated_at` = NOW()
WHERE `profile_id` = ?
]],
values = {
profileId
}
}
})
if not success then
print('Transaction failed')
end
Isolation Level จะเข้ามามีบทบาทเมื่อ Transaction ลักษณะนี้เกิดพร้อมกับ Transactions อื่น
③ mysql_transaction_isolation_level คืออะไร
oxmysql มี ConVar:
mysql_transaction_isolation_level
โดย Documentation ปัจจุบันกำหนด Mapping ดังนี้:
1 = Repeatable Read
2 = Read Committed
3 = Read Uncommitted
4 = Serializable
และค่า Default:
2
หรือ:
READ COMMITTED
④ ตั้งค่าใน FiveM ยังไง
ตัวอย่างใน server.cfg:
set mysql_transaction_isolation_level 2
หมายถึง:
READ COMMITTED
หรือ:
set mysql_transaction_isolation_level 1
หมายถึง:
REPEATABLE READ
Mapping นี้มาจาก oxmysql Transaction Documentation โดยตรง.
⑤ ค่า Default ของ oxmysql คืออะไร
ปัจจุบัน oxmysql ระบุ:
mysql_transaction_isolation_level = 2
ซึ่งเท่ากับ:
READ COMMITTED
ดังนั้น Server Owner ที่ไม่เคยตั้ง ConVar นี้เองไม่ควรสรุปว่า Transaction ของ oxmysql ใช้ REPEATABLE READ เพียงเพราะ MariaDB/InnoDB มี Default ของตัวเอง
ต้องแยก:
MariaDB default
กับ
oxmysql transaction configuration
ออกจากกัน
⑥ MariaDB Default คืออะไร
MariaDB Documentation ระบุว่า Default Isolation Level ของ InnoDB คือ:
REPEATABLE READ
แต่ oxmysql Transaction ConVar ใช้:
READ COMMITTED
เป็นค่า Default.
นี่เป็นหนึ่งในรายละเอียดที่ FiveM Developer ควรรู้มากที่สุดในหัวข้อนี้
⑦ READ UNCOMMITTED คืออะไร
READ UNCOMMITTED เป็น Isolation Level ต่ำที่สุดใน 4 ระดับ และ MariaDB ระบุว่าสามารถเกิด Dirty Read ได้ กล่าวคือ Transaction หนึ่งสามารถอ่านการเปลี่ยนแปลงที่ Transaction อื่นยังไม่ได้ Commit.
ตัวอย่าง:
Transaction A
UPDATE balance = 500
แต่ยังไม่ COMMIT
Transaction B
SELECT balance
↓
อาจเห็น 500
จากนั้นถ้า A:
ROLLBACK
ค่า 500 ที่ B เคยอ่านก็เป็นข้อมูลที่ไม่เคย Commit จริง
⑧ Dirty Read คืออะไร
ตัวอย่าง:
ข้อมูลจริงเดิม
balance = 1000
Transaction A:
UPDATE
balance = 500
ยังไม่ COMMIT
Transaction B ที่ใช้ READ UNCOMMITTED:
SELECT balance
→ เห็น 500
ต่อมา Transaction A:
ROLLBACK
ข้อมูลจริงกลับเป็น:
1000
แต่ Transaction B เคยใช้ค่า:
500
ไปแล้ว
นี่คือ Dirty Read ตามพฤติกรรมของ READ UNCOMMITTED ที่ MariaDB ระบุไว้.
⑨ FiveM ควรใช้ READ UNCOMMITTED ไหม
ไม่ควรเลือกเพียงเพราะคิดว่า:
Lock น้อย
=
เร็วที่สุด
=
ดีที่สุด
เพราะ Resource ที่อ่านข้อมูลซึ่งยังไม่ได้ Commit สามารถนำ State ที่ไม่เคยเกิดขึ้นจริงไปใช้ต่อได้
โดยเฉพาะข้อมูลที่ต้องการความสอดคล้อง เช่น:
Character State
Persistent Settings
Ownership
Counters
Workflow State
ต้องพิจารณา Consistency ก่อน Performance
⑩ READ COMMITTED คืออะไร
MariaDB ระบุว่าใน READ COMMITTED แต่ละ Query ภายใน Transaction จะเห็นเฉพาะข้อมูลที่ Commit ก่อน Query นั้นเริ่ม และแต่ละ Consistent Read จะสร้าง Snapshot ใหม่ของตัวเอง.
แนวคิด:
Transaction A
SELECT → Snapshot 1
Transaction B
UPDATE
COMMIT
Transaction A
SELECT อีกครั้ง
→ Snapshot ใหม่
→ อาจเห็นค่าของ B
นี่ต่างจาก REPEATABLE READ อย่างสำคัญ
⑪ READ COMMITTED ป้องกัน Dirty Read
เพราะ Query จะเห็นเฉพาะข้อมูลที่ Commit แล้วก่อน Query นั้นเริ่ม.
ดังนั้น:
Transaction B
แก้ข้อมูล
แต่ยังไม่ COMMIT
Transaction A ที่ใช้ READ COMMITTED จะไม่อ่านค่าที่ยังไม่ Commit นั้นเป็น Normal Consistent Read
⑫ แต่ READ COMMITTED อ่านค่าไม่เหมือนเดิมได้
สมมติ:
Transaction A
SELECT status
→ online
จากนั้น:
Transaction B
UPDATE status = offline
COMMIT
Transaction A Query รอบใหม่:
SELECT status
→ offline
เพราะ MariaDB ระบุว่า READ COMMITTED สร้าง Fresh Snapshot สำหรับแต่ละ Consistent Read.
พฤติกรรมนี้มักเรียกว่า:
Non-repeatable read
ในทางแนวคิด
⑬ READ COMMITTED เป็น Default ของ oxmysql
สำหรับ MySQL.transaction ของ oxmysql ค่า ConVar Default คือ:
2
ซึ่ง Map เป็น:
Read Committed
ดังนั้นก่อนเปลี่ยน Isolation Level ควรถามก่อนว่า:
Resource มีปัญหาอะไรที่ READ COMMITTED แก้ไม่ได้จริง?
ไม่ควรเปลี่ยนเพียงเพราะเห็น Database Server อื่นใช้ Level ต่างกัน
⑭ READ COMMITTED กับ Gap Lock
MariaDB InnoDB Lock Documentation ระบุว่า Gap Locking ถูกปิดเมื่อ Transaction Isolation Level เป็น READ COMMITTED ในบริบทที่เอกสารอธิบายเกี่ยวกับ InnoDB Gap Locks.
นี่เป็นหนึ่งในความแตกต่างด้าน Locking ที่ทำให้ Isolation Level มีผลต่อ Concurrent Database Workload ไม่ใช่เพียงผลลัพธ์ของ SELECT
⑮ REPEATABLE READ คืออะไร
MariaDB ระบุว่า REPEATABLE READ เป็น Default InnoDB Isolation Level และ Consistent Reads ทั้งหมดภายใน Transaction เดียวกันจะอ่าน Snapshot ที่ถูกสร้างจาก Consistent Read แรก.
แนวคิด:
Transaction A
SELECT
→ Snapshot A
Transaction B
UPDATE
COMMIT
Transaction A
SELECT อีกครั้ง
→ ยังอ่าน Snapshot A
จึงได้มุมมองข้อมูลที่คงที่กว่า READ COMMITTED ตลอด Transaction
⑯ READ COMMITTED กับ REPEATABLE READ ต่างกันตรงไหน
READ COMMITTED
Query 1
→ Snapshot 1
มี Transaction อื่น Commit
Query 2
→ Snapshot 2
MariaDB ระบุว่าแต่ละ Consistent Read จะสร้าง Snapshot ใหม่.
REPEATABLE READ
Query 1
→ Snapshot A
มี Transaction อื่น Commit
Query 2
→ Snapshot A
Consistent Reads ใน Transaction เดียวกันยังใช้ Snapshot ที่สร้างจาก Read แรก.
⑰ ตัวอย่าง FiveM READ COMMITTED
สมมติ Transaction โหลด:
Player Status
↓
ทำ Query อื่น
↓
อ่าน Player Status อีกครั้ง
ระหว่างสอง Queries มี Resource อีกตัว Update และ Commit
READ COMMITTED สามารถทำให้ Query รอบสองเห็นค่าที่ใหม่กว่า Query รอบแรกได้ เพราะแต่ละ Read ใช้ Fresh Snapshot.
⑱ ตัวอย่าง FiveM REPEATABLE READ
Transaction เดียวกัน:
SELECT player setting
→ dark
Resource อื่น:
UPDATE setting = light
COMMIT
Transaction แรกทำ Consistent Read อีกครั้ง:
SELECT player setting
ภายใต้ REPEATABLE READ จะยังอ้างอิง Snapshot เดิมของ Transaction ตามหลักที่ MariaDB ระบุ.
⑲ REPEATABLE READ ดีกว่า READ COMMITTED ไหม
ไม่สามารถตอบว่า “ดีกว่า” โดยไม่รู้ Requirement
REPEATABLE READ เหมาะเมื่อ Transaction ต้องการ Stable Read View มากกว่า
READ COMMITTED เหมาะเมื่อแต่ละ Queryควรเห็นข้อมูล Commit ล่าสุดก่อน Query นั้นเริ่ม
เลือกจาก:
Business Rule
Transaction Length
Concurrency
Lock Behavior
Database Workload
ไม่ใช่เลือก Isolation ที่เลขสูงกว่า
⑳ SERIALIZABLE คืออะไร
MariaDB ระบุว่า SERIALIZABLE เป็น Isolation Level สูงสุด และมีพฤติกรรมคล้าย REPEATABLE READ แต่เมื่อ autocommit ปิด จะเปลี่ยน Plain SELECT เป็น Locking Read ลักษณะ SELECT ... LOCK IN SHARE MODE โดยอัตโนมัติ.
นั่นหมายความว่า Plain Reads สามารถมีผลด้าน Locking มากขึ้นกว่าระดับที่ต่ำกว่า
㉑ SERIALIZABLE ปลอดภัยที่สุดไหม
ในแง่ Isolation:
เข้มที่สุด
แต่ไม่ได้หมายความว่าเหมาะที่สุดสำหรับ FiveM
จากพฤติกรรมที่ MariaDB ระบุว่า Plain SELECT สามารถถูกเปลี่ยนเป็น Locking Reads ภายใต้เงื่อนไขของ SERIALIZABLE จึงอนุมานได้ว่า Workload ที่มี Concurrency สูงอาจเกิด Blocking/Lock Contention มากขึ้นเมื่อเทียบกับ Isolation ที่ผ่อนคลายกว่า.
ดังนั้นอย่าตั้ง:
4 = SERIALIZABLE
เพียงเพราะคิดว่า:
4 สูงกว่า 2
=
ดีกว่า 2
㉒ Isolation Level ยิ่งสูง Server ยิ่งช้าหรือไม่
ไม่ควรใช้กฎตายตัวแบบนั้น
ผลจริงขึ้นกับ:
Queries
Reads/Writes
Transaction Duration
Indexes
Concurrent Players
Resource Design
แต่ระดับ Isolation ที่เข้มขึ้นสามารถเพิ่มข้อจำกัดด้าน Concurrent Access ในบาง Workload
Performance ต้อง Benchmark จริง
oxmysql ระบุว่า Query Speeds เปลี่ยนตาม Hardware, Database Settings, Database Version และ Current Workload.
㉓ ตารางเปรียบเทียบ Isolation Level
| Level | สิ่งสำคัญ |
|---|---|
| READ UNCOMMITTED | อนุญาต Dirty Reads |
| READ COMMITTED | แต่ละ Consistent Read ใช้ Fresh Snapshot |
| REPEATABLE READ | Consistent Reads ใน Transaction ใช้ Snapshot เดิม |
| SERIALIZABLE | Isolation สูงสุด และเพิ่ม Locking Read Behavior |
พฤติกรรมเหล่านี้ตรงกับ MariaDB Transaction Isolation Documentation.
㉔ ตาราง oxmysql Mapping
| ConVar Value | Isolation Level |
|---|---|
1 | Repeatable Read |
2 | Read Committed |
3 | Read Uncommitted |
4 | Serializable |
Default:
2 = Read Committed
㉕ ถ้าไม่ได้ใช้ MySQL.transaction Isolation Level สำคัญไหม
Isolation Level มีความหมายโดยเฉพาะกับ Transactional Operations
ถ้า Resource ทำ SQL Statement เดี่ยวๆ ภายใต้ Autocommit Behavior ก็ยังมี Transaction Semantics ที่ Database Engine จัดการ แต่ผลที่ Developerสังเกตชัดที่สุดมักเกิดกับหลาย Statements ที่อยู่ใน Explicit Transaction
MariaDB ระบุว่า COMMIT จะจบ Transaction และทำให้การเปลี่ยนแปลงถูกบันทึก ขณะที่เมื่อ autocommit=1 จะมี Implicit Commit หลังแต่ละ Statement ตามพฤติกรรมที่เอกสารกำหนด.
㉖ COMMIT คืออะไร
COMMIT จบ Transaction และบันทึกการเปลี่ยนแปลงให้กลายเป็นข้อมูลที่ Transaction อื่นสามารถเห็นได้ตาม Isolation Rules.
แนวคิด:
BEGIN
↓
UPDATE
↓
UPDATE
↓
COMMIT
หลัง Commit Changes จะไม่ใช่ Uncommitted Data อีกต่อไป
㉗ ROLLBACK คืออะไร
MariaDB ระบุว่า ROLLBACK จะยกเลิก Changes ภายใน Transaction และทำให้การเปลี่ยนแปลงนั้นไม่ถูกเปิดเผยเป็นข้อมูล Commit ต่อ Transactions อื่น.
แนวคิด:
BEGIN
↓
UPDATE
↓
เกิด Error
↓
ROLLBACK
ข้อมูลกลับไปตาม State ก่อน Transaction ในขอบเขตที่ Rollback ครอบคลุม
㉘ Isolation Level ไม่ได้แทน Transaction
การตั้ง:
READ COMMITTED
ไม่ได้ทำให้ Queries หลายตัวกลายเป็น Atomic Operation โดยอัตโนมัติ
ถ้าต้องการ:
Query A สำเร็จ
+
Query B สำเร็จ
หรือ
ไม่ Commit ทั้งคู่
ต้องใช้ Transaction
oxmysql ระบุ MySQL.transaction ไว้สำหรับ Use Case นี้โดยตรง.
㉙ Transaction ไม่ได้แทน Isolation Level
ในทางกลับกัน การใช้ Transaction อย่างเดียวไม่ได้ตอบว่า:
Transaction จะเห็นข้อมูลของ Transaction อื่นแบบไหน
Isolation Level เป็นตัวกำหนด Behavior ด้าน Visibility/Isolation เพิ่มเติม
ดังนั้น:
Transaction
+
Isolation Level
เป็นคนละ Concept ที่ทำงานร่วมกัน
㉚ Isolation Level ไม่ได้แทน Lock Design
ถึงเลือก READ COMMITTED แล้ว Resource ยังสามารถเกิด:
Deadlock
Lock Wait
Hot Row
ได้ถ้า Transaction Design ไม่ดี
Isolation เป็นเพียงหนึ่งส่วนของ Concurrency Design
ยังต้องดู:
Lock Order
Transaction Length
Query Plan
Indexes
ด้วย
㉛ เปลี่ยนเป็น READ COMMITTED เพื่อแก้ Deadlock ได้ไหม
ไม่ควรเปลี่ยนโดยหวังว่าจะเป็น Universal Deadlock Fix
READ COMMITTED มี Locking/Snapshot Behavior ต่างจาก REPEATABLE READ รวมถึง Gap Lock Behavior บางส่วน แต่ Deadlock ยังสามารถเกิดจาก Transactions ที่ถือ Locks แล้วรอกันเป็นวงจรได้.
แก้ Deadlock ต้องดู Deadlock Report และ Transaction Order จริง
㉜ เปลี่ยนเป็น SERIALIZABLE เพื่อแก้ข้อมูลชนกันดีไหม
ไม่ควรทำเป็นขั้นแรก
SERIALIZABLE เพิ่ม Isolation และ MariaDB ระบุว่า Plain SELECT สามารถถูกเปลี่ยนเป็น Locking Read เมื่อ Autocommit ปิด.
ดังนั้นอาจเพิ่ม:
Blocking
Lock Wait
Concurrency Pressure
ใน Workload บางประเภท
ต้อง Load Test ก่อนใช้กับ FiveM Production
㉝ READ UNCOMMITTED ทำให้ Server เร็วที่สุดไหม
ไม่สามารถสรุปแบบนั้น
แม้ระดับนี้ผ่อนคลายเรื่อง Visibility มากที่สุดและอนุญาต Dirty Reads แต่ Performance รวมยังขึ้นกับ:
SQL
Indexes
Database Hardware
Writes
Query Count
Network
และ oxmysql ย้ำว่า Query Speeds แตกต่างตาม Environment และ Current Workload.
อย่าแลก Data Consistency เพื่อหวัง Performance โดยไม่มี Benchmark
㉞ Isolation Level กับ Deadlock
Isolation Level สามารถเปลี่ยน Locking Behavior และ Snapshot Semantics แต่ Deadlock Root Cause มักต้องวิเคราะห์:
Transaction A
↓
Lock X
↓
รอ Y
Transaction B
↓
Lock Y
↓
รอ X
ดังนั้นเมื่อเจอ Deadlock ให้แก้:
Order
Duration
Query
Hot Rows
ร่วมด้วย
㉟ Isolation Level กับ Lock Wait Timeout
Lock Wait Timeout เกิดเมื่อ Transaction รอ Lock นานเกินไป
Isolation Level อาจมีผลต่อ Locks ที่ถูกสร้าง แต่:
เปลี่ยน Isolation
ไม่ใช่การแทน:
หา Blocking Transaction
ต้องตรวจทั้งสองเรื่องแยกกัน
㊱ Isolation Level กับ Gap Locks
MariaDB InnoDB Documentation ระบุว่า Gap Locks ใช้กับ Index Record Gaps และ Gap Locking ถูกปิดภายใต้ READ COMMITTED ในบริบทที่เอกสารอธิบาย.
นี่เป็นเหตุผลหนึ่งที่ Developer ที่กำลังวิเคราะห์:
Lock Contention
Deadlock
Range Updates
ควรรู้ว่า Isolation Level ปัจจุบันคืออะไร
㊲ Isolation Level กับ SELECT FOR UPDATE
SELECT ... FOR UPDATE เป็น Explicit Locking Read
ดังนั้นแม้ Isolation Level จะเป็น READ COMMITTED Resource ก็ยังสามารถสร้าง Locks ได้เมื่อใช้ Locking Statements
อย่าคิดว่า:
READ COMMITTED
=
ไม่มี Locks
InnoDB ยังใช้ Shared/Exclusive Locks เพื่อจัดการ Concurrent Access ตาม Operation.
㊳ Isolation Level กับ UPDATE
UPDATE ยังต้องใช้ Lock สำหรับ Rows ที่เกี่ยวข้องตาม InnoDB Concurrency Control
MariaDB ระบุว่า InnoDB ใช้ Row-level Shared และ Exclusive Locks รวมถึง Intention Locks เพื่อจัดการ Concurrent Transaction Access.
ดังนั้นแม้เปลี่ยน Isolation Level:
UPDATE Player Row พร้อมกัน
ก็ยังสามารถชนกันได้
㊴ Isolation Level กับ Cache
Cache เป็นเรื่อง:
ลด Database Queries
Isolation Level เป็นเรื่อง:
Transaction Visibility / Concurrency
คนละ Layer
อย่าเปลี่ยน Isolation Level เพื่อแก้ Resource ที่ Query Database ทุก Frame
ควรแก้ Query Architecture/Cache ก่อน
㊵ Isolation Level กับ Slow Query
Isolation Level ไม่ได้แก้ Missing Index หรือ Table Scan โดยตรง
ถ้า Query:
SELECT ...
ใช้ 2 วินาทีเพราะ Query Plan แย่
ให้ตรวจ:
EXPLAIN
Indexes
Rows scanned
ไม่ใช่เปลี่ยนจาก READ COMMITTED เป็น READ UNCOMMITTED ทันที
㊶ วิธีตรวจ oxmysql Isolation Level
เริ่มจาก server.cfg
ค้นหา:
mysql_transaction_isolation_level
ถ้าไม่มี Configuration Custom ค่า oxmysql Documentation ปัจจุบันระบุ Default เป็น:
2 = Read Committed
㊷ วิธีตรวจ MariaDB Session Isolation
MariaDB รองรับการกำหนด Isolation ทั้งในระดับ Global, Session และ Transaction ถัดไปผ่าน SET TRANSACTION โดยการตั้งโดยไม่ระบุ SESSION หรือ GLOBAL จะมีผลกับ Transaction ถัดไปที่ยังไม่เริ่ม และจากนั้นกลับไปใช้ Session Value.
นี่มีประโยชน์เมื่อ Debug Database Client โดยตรง
แต่ FiveM Server ที่ใช้ oxmysql ควรเข้าใจก่อนว่า oxmysql มี ConVar ของตัวเองสำหรับ MySQL.transaction.
㊸ SET TRANSACTION ใช้ยังไง
รูปแบบ SQL เช่น:
SET TRANSACTION
ISOLATION LEVEL
READ COMMITTED;
หรือใน Session Context ตาม Syntax ที่ MariaDB รองรับ.
แต่ไม่ควรให้ Resource แต่ละตัวเปลี่ยน Isolation แบบสุ่มโดยไม่มีมาตรฐาน เพราะจะทำให้ Troubleshooting ยากขึ้น
㊹ Global กับ Session ต่างกันอย่างไร
แนวคิด:
GLOBAL
→ ค่า Default ระดับ Server
SESSION
→ ค่าใน Connection/Session นั้น
TRANSACTION
→ Transaction ที่กำหนด
MariaDB SET TRANSACTION รองรับ Scope เหล่านี้ตาม Documentation และการเปลี่ยน Global Default ต้องใช้ Privilege ที่สูงกว่าการตั้ง Session.
สำหรับ Production ควรมี Configuration Strategy เดียวที่ชัดเจน
㊺ อย่าให้ Resource เปลี่ยน Global Isolation Level
Gameplay Resource ทั่วไปไม่ควรถือ Administrative Privilege เพื่อเปลี่ยน Global Database Defaults
ควรแยก:
Database Administration
ออกจาก:
FiveM Runtime User
ตาม Least Privilege
㊻ เปลี่ยน oxmysql Isolation Level ต้องทดสอบอะไร
อย่างน้อย:
① Player Login
② Character Load
③ Character Save
④ Concurrent Saves
⑤ Resource Transactions
⑥ Autosave
⑦ Deadlocks
⑧ Lock Waits
⑨ Query Latency
⑩ Database CPU
อย่าทดสอบเพียงว่า Server Start ได้
㊼ Benchmark ก่อนและหลัง
oxmysql ระบุว่า Real Query Speeds สามารถดูผ่าน Debug UI และ Server Console เมื่อเปิด mysql_debug และ Performance ขึ้นกับ Hardware, Database Settings, Version และ Current Workload.
ดังนั้นก่อนเปลี่ยน:
Isolation 2
→ Isolation 1
เก็บ Baseline ก่อน
แล้วเปรียบเทียบ:
Query latency
Deadlock count
Lock waits
CPU
Gameplay behavior
㊽ อย่าเปลี่ยนหลายอย่างพร้อมกัน
หลีกเลี่ยง:
Isolation Level
+
max_connections
+
wait_timeout
+
Indexes
พร้อมกัน
เพราะถ้าระบบดีขึ้นหรือแย่ลงจะไม่รู้ว่าตัวไหนเป็นสาเหตุ
ใช้:
วัด
↓
เปลี่ยน 1 เรื่อง
↓
วัดอีกครั้ง
㊾ FiveM Server ทั่วไปควรใช้ Level ไหน
ถ้า Server ใช้ oxmysql ตาม Default:
READ COMMITTED
เป็นจุดเริ่มต้นที่ oxmysql กำหนดไว้แล้ว.
ไม่ควรเปลี่ยนเว้นแต่มี Requirement ด้าน Transaction Semantics หรือ Concurrency ที่ชัดเจนและผ่านการทดสอบ
㊿ เมื่อไหร่ควรพิจารณา REPEATABLE READ
พิจารณาเมื่อ Business Operation ต้องการ:
Consistent Reads
ภายใน Transaction เดียว
และต้องการให้ Reads หลายครั้งเห็น Snapshot เดิมตามพฤติกรรมที่ MariaDB ระบุสำหรับ REPEATABLE READ.
แต่ต้อง Load Test Lock/Concurrency Behavior ของ Resource จริง
51. เมื่อไหร่ควรพิจารณา READ COMMITTED
พิจารณาเมื่อ Resource ต้องการให้แต่ละ Query ภายใน Transaction เห็นข้อมูล Commit ล่าสุดก่อน Query นั้นเริ่ม
MariaDB ระบุว่า READ COMMITTED สร้าง Fresh Snapshot ต่อ Consistent Read และ oxmysql ใช้ Level นี้เป็นค่า Default ของ MySQL.transaction.
52. เมื่อไหร่ควรหลีกเลี่ยง READ UNCOMMITTED
ถ้า Resource ไม่สามารถยอมรับ:
Dirty Read
ควรหลีกเลี่ยง เพราะ MariaDB ระบุว่าระดับนี้สามารถอ่าน Uncommitted Changes ได้.
สำหรับ Persistent Gameplay State ส่วนใหญ่ควรเข้าใจผลกระทบนี้ให้ชัดก่อนใช้
53. เมื่อไหร่ควรพิจารณา SERIALIZABLE
เฉพาะเมื่อ Requirement ต้องการ Isolation ที่เข้มมากจริง และยอมรับผลต่อ Concurrent Access ได้
MariaDB ระบุว่า SERIALIZABLE เป็นระดับสูงสุดและสามารถเปลี่ยน Plain SELECT เป็น Locking Read เมื่อ Autocommit ปิด.
ต้อง Load Test อย่างจริงจังก่อน Production
54. Isolation Level กับ Player Count
อย่าใช้สูตร:
Player เยอะ
→ ลด Isolation
Player น้อย
→ เพิ่ม Isolation
เพราะ Requirement จริงขึ้นกับ:
Concurrent Transactions
Data Access Pattern
Query Count
Rows ที่ชนกัน
Transaction Duration
มากกว่า Player Count เพียงอย่างเดียว
55. Isolation Level กับ Autosave
ถ้า Autosave สร้าง Transactions พร้อมกันจำนวนมาก Isolation Level สามารถมีผลต่อ Read/Lock Behavior
แต่ควรแก้:
Save Burst
Dirty Flag
Transaction Size
Hot Rows
ร่วมด้วย
ไม่ใช่พึ่ง Isolation Level อย่างเดียว
56. Isolation Level กับ Database Migration
Migration SQL มักเป็น Schema/DDL Operation ซึ่งเป็นอีกประเภทของ Database Work
อย่าเปลี่ยน Transaction Isolation Level เพื่อแก้:
Unknown column
Table doesn't exist
Migration failed
เพราะปัญหาเหล่านั้นอยู่คนละ Layer
57. Isolation Level กับ Too Many Connections
ไม่ใช่สิ่งเดียวกัน
Isolation Level
→ Transaction Semantics
max_connections
→ Connection Capacity
แต่ Transaction ที่ Block กันนานสามารถทำให้ Operations อยู่ในระบบนานขึ้น จึงอาจกระทบ Workload โดยอ้อม
ต้องวิเคราะห์ Metrics จริง
58. Isolation Level กับ wait_timeout
ไม่เกี่ยวกันโดยตรง
wait_timeout
→ Idle Connection
ส่วน:
Transaction Isolation
→ Visibility และ Lock Semantics
อย่าสับสนเพียงเพราะทั้งสองเป็น MariaDB Configuration
59. Isolation Level กับ innodb_lock_wait_timeout
innodb_lock_wait_timeout กำหนดเวลารอ InnoDB Lock
Isolation Level สามารถส่งผลต่อชนิด/รูปแบบ Locks ในบาง Operations แต่เป็นคนละ Configuration
หาก Lock Wait เกิด ให้หา Blocking Transaction ก่อน
60. Checklist ก่อนเปลี่ยน Isolation Level
ตรวจ:
ปัจจุบัน oxmysql ใช้ Level ไหน
มี
mysql_transaction_isolation_levelในserver.cfgหรือไม่Resource ไหนใช้
MySQL.transactionTransaction ไหนมีปัญหา
ต้องการ Snapshot แบบใด
Dirty Read ยอมรับได้หรือไม่
Reads ภายใน Transaction ต้องคงค่าเดิมหรือไม่
Concurrent Writes สูงหรือไม่
มี Deadlock หรือไม่
มี Lock Wait หรือไม่
มี SELECT FOR UPDATE หรือไม่
Transaction ยาวหรือไม่
มี Wait/Network Logic ใน Transaction หรือไม่
Query Order สม่ำเสมอหรือไม่
Index เหมาะหรือไม่
Autosave Burst หรือไม่
Hot Row หรือไม่
Query Latency ปัจจุบัน
Database CPU
Database RAM
Test Environment พร้อมหรือไม่
มี Baseline หรือไม่
เปลี่ยนทีละค่า
Load Test
Monitor Deadlocks
Monitor Lock Wait
Monitor Query Time
Test Player Save
Test Resource Restart
มี Rollback Config
ตารางเลือก Isolation Level แบบเข้าใจง่าย
| ต้องการ | Level ที่ควรศึกษา |
|---|---|
| ยอมรับ Dirty Read ได้ | READ UNCOMMITTED |
| แต่ละ Query เห็นข้อมูล Commit ล่าสุด | READ COMMITTED |
| Reads ใน Transaction เห็น Snapshot เดิม | REPEATABLE READ |
| Isolation เข้มมากและรับ Locking เพิ่มได้ | SERIALIZABLE |
นี่เป็นแนวทางเลือกจาก Semantics ไม่ใช่คำสั่งว่าทุก Server ต้องใช้ Level ใด Level หนึ่ง.
FiveM mysql_transaction_isolation_level คืออะไร
เป็น ConVar ของ oxmysql สำหรับกำหนด Transaction Isolation Level โดยใช้ค่า:
1 = Repeatable Read
2 = Read Committed
3 = Read Uncommitted
4 = Serializable
และ oxmysql ระบุ Default เป็น:
2
FiveM mysql_transaction_isolation_level ควรตั้งเท่าไร
ถ้าไม่มี Requirement ที่พิสูจน์ว่าต้องเปลี่ยน การเริ่มจาก Default ของ oxmysql:
2 = READ COMMITTED
เป็นทางเลือกที่สอดคล้องกับ Configuration ปัจจุบันของ Resource.
อย่าเปลี่ยนเพราะคำแนะนำจาก Server อื่นโดยไม่ทดสอบ
FiveM READ COMMITTED คืออะไร
แต่ละ Consistent Read จะใช้ Fresh Snapshot และเห็นเฉพาะข้อมูลที่ Commit ก่อน Query นั้นเริ่ม.
oxmysql ใช้ระดับนี้เป็น Transaction Isolation Default.
FiveM REPEATABLE READ คืออะไร
Consistent Reads ภายใน Transaction เดียวกันจะใช้ Snapshot ที่สร้างจาก Consistent Read แรก ทำให้ Reads ซ้ำเห็น View ที่คงที่กว่า.
MariaDB/InnoDB ใช้ระดับนี้เป็น Default ของ Database Engine โดยทั่วไป.
FiveM READ UNCOMMITTED คืออะไร
เป็นระดับที่อนุญาต Dirty Reads ทำให้ Transaction สามารถเห็นข้อมูลที่ Transaction อื่นยังไม่ได้ Commit.
จึงต้องระวังอย่างมากกับ Persistent Gameplay Data
FiveM SERIALIZABLE คืออะไร
เป็น Isolation Level สูงสุด และ MariaDB ระบุว่าเมื่อ Autocommit ปิด Plain SELECT จะถูกเปลี่ยนเป็น Locking Read ในลักษณะ Share Mode.
จึงต้องทดสอบ Concurrency อย่างจริงจัง
FiveM เปลี่ยน Isolation Level แล้วช่วย Deadlock ไหม
อาจเปลี่ยน Locking Behavior แต่ไม่ควรใช้เป็น Deadlock Fix แบบอัตโนมัติ
Deadlock ต้องตรวจ:
Transaction Order
Locks
Queries
Duration
ก่อน
FiveM READ COMMITTED ดีกว่า REPEATABLE READ ไหม
ไม่มีคำตอบเดียว
READ COMMITTED:
Fresh Snapshot ต่อ Query
REPEATABLE READ:
Stable Snapshot ภายใน Transaction
เลือกตาม Business Logic
FiveM SERIALIZABLE ทำให้ Server Lag ไหม
ไม่สามารถสรุปว่าจะ Lag เสมอ แต่จากพฤติกรรม Locking ที่เข้มขึ้นตาม MariaDB Documentation สามารถอนุมานได้ว่า Concurrent Workload บางประเภทอาจมี Blocking มากขึ้น.
ต้อง Benchmark จริงก่อน Production
FiveM Isolation Level เปลี่ยนใน server.cfg ยังไง
ตัวอย่าง:
set mysql_transaction_isolation_level 2
เท่ากับ:
READ COMMITTED
ตาม Mapping ของ oxmysql.
หลังเปลี่ยนให้ Test Resource Transactions และ Monitor Database Behavior
FAQ FiveM Transaction Isolation Level
Transaction Isolation Level คืออะไร
คือกฎที่กำหนดว่า Transactions ที่ทำงานพร้อมกันสามารถมองเห็นข้อมูลของกันและกันอย่างไร รวมถึงส่งผลต่อ Snapshot และ Locking Behavior
oxmysql มี Isolation Level กี่ระดับ
4 ระดับ ได้แก่ Repeatable Read, Read Committed, Read Uncommitted และ Serializable.
oxmysql ใช้ Isolation Level อะไรเป็น Default
READ COMMITTED โดย ConVar Default คือ 2.
MariaDB ใช้อะไรเป็น Default
MariaDB/InnoDB โดยทั่วไปใช้ REPEATABLE READ เป็น Default Isolation Level.
READ COMMITTED ต่างจาก REPEATABLE READ อย่างไร
READ COMMITTED ใช้ Fresh Snapshot ต่อ Consistent Read ส่วน REPEATABLE READ ใช้ Snapshot เดิมภายใน Transaction.
READ UNCOMMITTED อันตรายอย่างไร
สามารถเกิด Dirty Read หรืออ่านข้อมูลที่ Transaction อื่นยังไม่ได้ Commit.
SERIALIZABLE คืออะไร
เป็น Isolation Level สูงสุด และเพิ่ม Locking Behavior สำหรับ Reads ตามเงื่อนไขที่ MariaDB กำหนด.
Isolation Level แก้ Deadlock ได้ไหม
ไม่ใช่คำตอบโดยตรง ต้องตรวจ Transaction Order และ Locks ที่เกิดจริง
เปลี่ยน Isolation Level เพื่อให้ Query เร็วขึ้นดีไหม
ไม่ควรทำโดยไม่มี Benchmark เพราะ Query Performance ยังขึ้นกับ Hardware, Database Settings, Version และ Workload.
READ COMMITTED ทำ Dirty Read ไหม
Normal Consistent Reads จะเห็นเฉพาะข้อมูลที่ Commit แล้วก่อน Query เริ่ม.
REPEATABLE READ เหมาะเมื่อไร
เมื่อ Transaction ต้องการ Consistent Reads ที่อ้างอิง Snapshot เดิมตลอด Transaction ตาม Semantics ของ MariaDB.
ควรใช้ SERIALIZABLE กับ FiveM ทุก Server ไหม
ไม่ เพราะ Isolation ที่เข้มที่สุดไม่ได้หมายความว่าเหมาะกับทุก Concurrent Workload ต้องพิจารณา Requirement และ Load Test ก่อน
ประเด็นสำคัญ
สิ่งที่ FiveM Developer ต้องจำให้ชัดที่สุดคือ:
MariaDB/InnoDB Default
=
REPEATABLE READ
แต่
oxmysql MySQL.transaction Default
=
READ COMMITTED
oxmysql กำหนด Mapping:
1 = REPEATABLE READ
2 = READ COMMITTED
3 = READ UNCOMMITTED
4 = SERIALIZABLE
และใช้:
2
เป็น Default.
ความแตกต่างหลักคือ:
READ UNCOMMITTED
→ เห็น Uncommitted Data ได้
READ COMMITTED
→ Fresh Snapshot ต่อ Query
REPEATABLE READ
→ Snapshot เดิมภายใน Transaction
SERIALIZABLE
→ Isolation เข้มที่สุดและเพิ่ม Locking
สำหรับ FiveM Server อย่าเปลี่ยน Isolation Level เพียงเพื่อแก้ Deadlock, Slow Query หรือ Lock Wait แบบลองผิดลองถูก เพราะแต่ละปัญหาต้องวิเคราะห์คนละ Layer
แนวทางที่ดีกว่าคือ:
ดู Transaction
↓
ดู Requirement
↓
ดู Isolation ปัจจุบัน
↓
เก็บ Baseline
↓
เปลี่ยนเฉพาะเมื่อมีเหตุผล
↓
Load Test
↓
ตรวจ Deadlock / Lock Wait / Query Time
สำหรับผู้อ่าน comsiam ให้จำสูตร “Isolation Level ไม่ใช่ระดับความแรง แต่เป็นระดับการแยก Transaction” และ comsiam แนะนำให้คงค่า Default ของ oxmysql ไว้ก่อน หากยังไม่มีปัญหาหรือ Business Requirement ที่พิสูจน์ว่าต้องเปลี่ยน เพราะการเปลี่ยน Transaction Isolation สามารถแก้ Behavior หนึ่ง แต่สร้าง Locking หรือ Consistency Behavior ใหม่ในอีกส่วนของ Server ได้
Comments
Post a Comment