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 READConsistent Reads ใน Transaction ใช้ Snapshot เดิม
SERIALIZABLEIsolation สูงสุด และเพิ่ม Locking Read Behavior

พฤติกรรมเหล่านี้ตรงกับ MariaDB Transaction Isolation Documentation.

㉔ ตาราง oxmysql Mapping

ConVar ValueIsolation Level
1Repeatable Read
2Read Committed
3Read Uncommitted
4Serializable

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

ตรวจ:

  1. ปัจจุบัน oxmysql ใช้ Level ไหน

  2. มี mysql_transaction_isolation_level ใน server.cfg หรือไม่

  3. Resource ไหนใช้ MySQL.transaction

  4. Transaction ไหนมีปัญหา

  5. ต้องการ Snapshot แบบใด

  6. Dirty Read ยอมรับได้หรือไม่

  7. Reads ภายใน Transaction ต้องคงค่าเดิมหรือไม่

  8. Concurrent Writes สูงหรือไม่

  9. มี Deadlock หรือไม่

  10. มี Lock Wait หรือไม่

  11. มี SELECT FOR UPDATE หรือไม่

  12. Transaction ยาวหรือไม่

  13. มี Wait/Network Logic ใน Transaction หรือไม่

  14. Query Order สม่ำเสมอหรือไม่

  15. Index เหมาะหรือไม่

  16. Autosave Burst หรือไม่

  17. Hot Row หรือไม่

  18. Query Latency ปัจจุบัน

  19. Database CPU

  20. Database RAM

  21. Test Environment พร้อมหรือไม่

  22. มี Baseline หรือไม่

  23. เปลี่ยนทีละค่า

  24. Load Test

  25. Monitor Deadlocks

  26. Monitor Lock Wait

  27. Monitor Query Time

  28. Test Player Save

  29. Test Resource Restart

  30. มี 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

Popular posts from this blog

FiveM ยังน่าเล่นไหม? Enhanced เปลี่ยน FiveM แค่ไหน

FiveM คืออะไร เล่นอย่างไร สำหรับมือใหม่ เริ่มต้นตั้งแต่ศูนย์

วิธีตั้ง Admin Permission ด้วย add_ace และ add_principal FiveM แบบละเอียด