معاملات قواعد البيانات ومستويات العزل: القراءة غير النظيفة، الأطياف، و MVCC
شرح معماري لمعاملات ACID ومستويات العزل الأربعة والظواهر الناتجة عنها وكيف تعمل محركات قواعد البيانات بنظام MVCC لتفادي أقفال القراءة.
💳 Transactions & Isolation Levels
الكود ممكن يكون شغال 100%…
والـ API ممكن ترجع 200 OK…
لكن البيانات نفسها تكون غلط.
📚 المحتويات
- سؤال الانترفيو
- المشكلة: Two Transfers at Once
- يعني إيه Transaction؟
- Commit و Rollback
- ACID
- Isolation
- Concurrency Problems
- Dirty Read
- Lost Update
- Non-Repeatable Read
- Phantom Read
- Write Skew
- Concurrency Control
- Locks
- MVCC
- Isolation Levels
- Read Uncommitted
- Read Committed
- Repeatable Read
- Serializable
- Snapshot Isolation
- Database Differences
- المثال البنكي الصحيح
- Deadlocks
- اختيار Isolation Level
- ملحوظات مهمة
- إجابة انترفيو جاهزة
- الخلاصة
- مصادر رسمية
🎯 سؤال الانترفيو
عندك تطبيق بنكي.
رصيد العميل:
1000 EGP
وفجأة العميل فتح التطبيق من:
Mobile
Laptop
وفي نفس الوقت تقريبًا:
Mobile → Transfer 800
Laptop → Transfer 800
المفروض:
Transaction A → SUCCESS
Transaction B → REJECTED
لأن الرصيد لا يكفي للعملية الثانية.
لكن لو السيستم متصمم غلط:
A reads balance = 1000
B reads balance = 1000
A → transfer 800
B → transfer 800
Final:
1600 transferred
Balance logic violated ❌
المشكلة هنا مش:
Syntax Error
NullReferenceException
Server Crash
المشكلة:
Data Integrity
الكود ممكن يكون شغال تمام.
لكن الـ state النهائي للنظام غلط.
ودي من أخطر مشاكل الـ Production.
💡 يعني إيه Transaction؟
تخيل تحويل بنكي:
1. خصم من الحساب الأول
2. إضافة للحساب الثاني
3. تسجيل عملية التحويل
4. تحديث البيانات المطلوبة
دي مش مجموعة عمليات منفصلة بالنسبة للـ business.
دي:
Transaction
أي:
مجموعة عمليات تُعامل كوحدة منطقية واحدة.
لو كل شيء نجح:
COMMIT
لو حصل failure:
ROLLBACK
الفكرة الأساسية:
ALL
OR
NOTHING
لكن خلي بالك:
Transaction وحدها لا تحل كل مشاكل الـ concurrency.
وده أهم جزء في الموضوع.
🔐 Commit و Rollback
Commit
يعني:
ثبت التغييرات نهائيًا.
BEGIN
↓
UPDATE
↓
INSERT
↓
COMMIT
Rollback
يعني:
ألغِ تغييرات الـ transaction حسب قواعد الـ DB.
BEGIN
↓
UPDATE
↓
ERROR
↓
ROLLBACK
🧱 ACID
الـ Transactions مرتبطة بأربع خصائص مشهورة:
A → Atomicity
C → Consistency
I → Isolation
D → Durability
Atomicity
يا كل العملية تنجح، يا لا شيء منها ينجح.
Consistency
الـ transaction لا تترك البيانات في حالة تخالف قواعد الـ database/business invariants المفروضة عليها.
Isolation
الـ concurrent transactions لا تتداخل بشكل يؤدي إلى نتائج غير مقبولة حسب مستوى العزل المستخدم.
Durability
بعد نجاح الـ commit، التغييرات يجب أن تبقى محفوظة حتى مع بعض أنواع failures، وفق ضمانات قاعدة البيانات.
وده هيكون موضوع مهم لوحده:
Durability
🧩 Isolation
دلوقتي عندنا:
Transaction A
Transaction B
Transaction C
...
كلهم شغالين في نفس الوقت.
السؤال:
كل Transaction تشوف إيه من شغل الـ Transactions التانية؟
هنا يظهر:
Isolation
وهو جزء الـ I في ACID.
والـ Isolation Level هو اللي بيحدد درجة العزل والسلوك المتوقع أثناء الـ concurrency.
لكن مهم جدًا:
Isolation Level مش معناه طريقة تنفيذ واحدة في كل Database.
نفس الاسم ممكن يتنفذ باستخدام:
Locks
Row Versioning
MVCC
أو خليط بينهم
حسب الـ DBMS.
⚠️ Concurrency Problems
خلينا نشوف المشاكل اللي ممكن تحصل.
🩸 Dirty Read
Transaction A:
Balance = 1000
تغيره إلى:
5000
لكن لسه:
COMMIT ❌
Transaction B تقرأ:
5000
بعدها A تفشل:
ROLLBACK
فتختفي الـ 5000.
B كانت قرأت:
بيانات غير committed.
وده:
Dirty Read
وده ممكن يؤدي لقرارات مبنية على state لم تصبح حقيقة نهائية.
👻 Lost Update
الرصيد:
1000
Transaction A تقرأ:
1000
Transaction B تقرأ:
1000
A تحسب:
1000 + 500 = 1500
وتكتب:
1500
B تحسب من القيمة القديمة:
1000 - 200 = 800
وتكتب:
800
النتيجة:
800
فين الـ 500؟
اختفت.
آخر write غطى على أول write.
وده:
Lost Update
مهم:
منع Lost Update مش مجرد "أنا استخدمت Transaction".
لازم transaction/concurrency strategy تحمي الـ read-modify-write operation.
ممكن تستخدم مثلًا:
Atomic UPDATE
Optimistic Concurrency
Pessimistic Locking
Appropriate Isolation
حسب الحالة.
🔄 Non-Repeatable Read
Transaction A تقرأ:
Balance = 1000
تعمل عمليات أخرى داخل نفس transaction.
ثم تقرأ نفس الـ row مرة ثانية.
لكن Transaction B كانت عملت:
UPDATE balance = 2000
COMMIT
فتكون النتيجة:
First read → 1000
Second read → 2000
نفس transaction.
نفس البيانات.
لكن القيمة تغيرت بين القراءتين.
وده:
Non-Repeatable Read
👻 Phantom Read
Transaction A تعمل:
SELECT *
FROM Accounts
WHERE Balance > 10000;
النتيجة:
10 rows
ثم Transaction B تعمل:
INSERT ...
بحيث الحساب الجديد يحقق الشرط.
Transaction A تعيد نفس الاستعلام:
11 rows
ظهر Row جديد يحقق نفس predicate.
ده:
Phantom Read
والـ Phantom Reads ممكن تكون مهمة في:
Reports
Validation
Limits
Pagination
Range queries
Business rules
لكن شكلها الدقيق يعتمد على الـ DBMS والـ isolation implementation.
⚠️ Write Skew
دي من المشاكل الأهم في التفكير في الـ concurrency.
عندك rule:
لازم يفضل فيه Doctor واحد على الأقل On Call.
حالياً:
Ahmed → On Call
Mohamed → On Call
Transaction A تقرأ:
Mohamed is On Call
فتشيل Ahmed.
Transaction B تقرأ:
Ahmed is On Call
فتشيل Mohamed.
كل واحدة منفردة ممكن تبدو صحيحة.
لكن بعد ما الاتنين يعملوا Commit:
Ahmed → OFF
Mohamed → OFF
الـ business invariant اتكسر.
وده:
Write Skew
وهنا بتفهم ليه:
المشكلة مش دائمًا في نفس الـ row.
أحيانًا المشكلة في:
Relationship
Predicate
Business Invariant
Multiple Rows
وده أحد الأسباب اللي تخلي بعض السيناريوهات تحتاج isolation أقوى أو locking/constraint strategy مناسبة.
⚙️ Concurrency Control
إزاي Database تتعامل مع كل ده؟
هنا عندك مجموعة تقنيات، أهمها:
Locks
MVCC
Row Versioning
Optimistic Concurrency
Pessimistic Concurrency
Isolation Levels
Constraints
🔒 Locks
قاعدة البيانات ممكن تعمل Lock على resources.
مثلاً:
Transaction A
↓
Account #123
↓
LOCK
Transaction B تحاول تعدل نفس resource:
Transaction B
↓
Account #123
↓
WAIT
لحد ما الـ lock يتحرر أو العملية تفشل حسب السيناريو.
الـ DBMS ممكن تستخدم أنواع مختلفة من locks ومستويات مختلفة من granularity، مثل:
Row
Page
Table
Key Range
حسب النظام والاستعلام والـ isolation.
في SQL Server مثلًا توجد Shared وUpdate وExclusive locks، بالإضافة إلى key-range locks مع SERIALIZABLE. citeturn0search0
🧠 ليه منقفلش كل حاجة؟
لأن:
More Locks
↓
More Blocking
↓
More Waiting
↓
Less Concurrency
وممكن تدخل في:
Deadlock
مثلاً:
Transaction A locks Account 1
Transaction B locks Account 2
A waits for Account 2
B waits for Account 1
فتبقى:
A → waiting for B
B → waiting for A
الـ DBMS لازم تكسر الـ cycle بإلغاء/rollback واحدة من العمليات، وعلى التطبيق يكون مستعد يتعامل مع الـ retry حسب النظام.
عشان كده:
Transaction لازم تكون قصيرة قدر الإمكان.
وده أيضًا من توصيات Microsoft عند التعامل مع SQL Server لتقليل blocking والـ contention. citeturn0search0
🧬 MVCC
طريقة مختلفة.
بدل ما كل Read تستنى Write:
قاعدة البيانات تحتفظ بنسخ/إصدارات من البيانات تسمح للـ readers برؤية snapshot مناسب.
MVCC:
Multi-Version
Concurrency Control
مثلاً:
Row Version 1
Balance = 1000
Row Version 2
Balance = 2000
Transaction قديمة ممكن تشوف version مناسبة لها.
Transaction أحدث تشوف version أحدث.
الميزة:
Less Blocking
Higher Read Concurrency
Consistent Reads
لكن MVCC مش "مجاني".
فيه تكلفة مرتبطة بـ:
Version Storage
Cleanup
Memory / Disk
Transaction Lifetime
Conflict Detection
وطريقة التنفيذ تختلف من Database لأخرى.
PostgreSQL يعتمد على MVCC كجزء أساسي من concurrency control، ويشرح رسميًا كيف تختلف مستويات isolation في هذا النموذج. citeturn0search2
📊 Isolation Levels
المستويات التقليدية:
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
وبعض الأنظمة تضيف/تدعم مستويات أو أوضاع versioning مثل:
SNAPSHOT
READ COMMITTED SNAPSHOT
لكن لا تفترض إن كل DBMS عندها نفس defaults أو نفس التنفيذ.
1️⃣ READ UNCOMMITTED
أقل مستوى عزل.
ممكن يسمح بـ:
Dirty Read
Non-Repeatable Read
Phantom Read
الفكرة:
Maximum Concurrency
Minimum Read Protection
مفيد فقط في حالات محددة جدًا عندما تكون الدقة أقل أهمية من تقليل read blocking.
ومش مناسب للعمليات المالية الحساسة.
SQL Server يصفه كأقل مستوى isolation ويسمح فيه بقراءة تغييرات غير committed. citeturn0search0
2️⃣ READ COMMITTED
من أكثر المستويات استخدامًا.
الفكرة:
لا تقرأ بيانات غير committed.
في SQL Server هو الـ default isolation level التقليدي، لكن طريقة القراءة نفسها قد تكون بالـ locks أو row versioning حسب إعدادات قاعدة البيانات. citeturn0search0
في SQL Server عندما يكون READ_COMMITTED_SNAPSHOT غير مفعّل:
Read
↓
Shared Lock
↓
Statement finishes
↓
Read lock released
أما عند تفعيل READ_COMMITTED_SNAPSHOT:
Read
↓
Committed row version
بدون نفس نمط shared row/page locking للقراءات. citeturn0search0
في PostgreSQL، READ COMMITTED هو الـ default أيضًا، لكن semantics مبنية على MVCC: كل statement يرى rows committed قبل بداية ذلك الـ statement. citeturn0search3
يمنع غالبًا:
Dirty Read
لكنه قد يسمح:
Non-Repeatable Read
Phantom Read
وكذلك read-modify-write race قد تحتاج حماية إضافية حسب طريقة تنفيذ العملية.
3️⃣ REPEATABLE READ
هنا بنشدد العزل أكثر.
الفكرة:
البيانات التي قرأتها داخل transaction لا تتغير عليك بالطريقة التي تسمح بـ non-repeatable read وفق semantics الخاصة بالـ DBMS.
في SQL Server، يتم الاحتفاظ بالـ read/write locks على الموارد المختارة حتى نهاية transaction، لكن لا يتم منع phantom rows بنفس طريقة SERIALIZABLE. citeturn0search0
في MySQL InnoDB، REPEATABLE READ هو الـ default، والـ consistent nonlocking reads داخل transaction تعتمد على snapshot established by the first read، بينما locking reads تستخدم locking strategies مختلفة مثل next-key/gap locks حسب الاستعلام. citeturn0search1
وده مثال ممتاز ليه لازم تعرف:
إنت شغال على أنهي Database؟
لأن الاسم واحد، لكن التنفيذ والـ semantics التفصيلية تختلف.
4️⃣ SERIALIZABLE
ده أعلى مستوى isolation تقليدي.
الفكرة:
النتيجة تكون مكافئة لتنفيذ الـ transactions بشكل متسلسل بدل تداخلها بشكل يؤدي لنتيجة غير مسموحة.
في SQL Server، SERIALIZABLE يستخدم أيضًا key-range locks لحماية ranges ومنع phantom insertions التي تحقق نفس predicate. citeturn0search0
في PostgreSQL، SERIALIZABLE لا يعني بالضرورة إن كل transaction تستنى الأخرى؛ النظام قد يكتشف أن النتيجة لا يمكن أن تحدث في execution serial، ويعمل rollback لإحدى العمليات مع serialization_failure. citeturn0search3
وده فرق مهم جدًا.
يعني:
Serializable
≠
"Database locks everything forever"
الآلية تختلف.
الميزة:
حماية قوية جدًا للـ concurrency.
العيب:
More contention
More waiting
More conflicts
Potential retries
Lower throughput in some workloads
📸 Snapshot Isolation
ده موجود في أنظمة معينة كـ isolation mode مستقل.
مثلاً في SQL Server:
SNAPSHOT
يعتمد على row versioning.
Transaction تشوف snapshot transaction-level للبيانات كما كانت عند نقطة مناسبة من بداية transaction.
مثال:
Balance = 1000
Transaction A starts
Transaction B
↓
Balance = 2000
↓
COMMIT
Transaction A reads again
↓
1000
لأن A تعمل على snapshot الخاصة بها.
SQL Server يوثق SNAPSHOT كـ transaction-level row-versioning isolation، مع اختلافه عن READ COMMITTED SNAPSHOT الذي يعطي statement-level consistency. citeturn0search0
🆚 Snapshot vs RCSI في SQL Server
دي نقطة مهمة جدًا.
READ COMMITTED SNAPSHOT
كل statement يحصل على snapshot:
Statement 1 → Snapshot A
Statement 2 → Snapshot B
ممكن statement ثانية ترى commits أحدث من statement الأولى.
SNAPSHOT
الـ transaction نفسها لها consistent snapshot:
Transaction
↓
Snapshot A
↓
Statement 1 → A
Statement 2 → A
Statement 3 → A
وده فرق مهم في الـ consistency model.
Microsoft توضح أن RCSI يعطي statement-level read consistency، بينما SNAPSHOT يعطي transaction-level read consistency. citeturn0search0
🌍 نفس Isolation Level ≠ نفس التنفيذ
ودي من أهم نقاط البوست.
SQL Server
الـ default التقليدي:
READ COMMITTED
ويمكنه استخدام:
Locks
أو:
Row Versioning
حسب إعدادات مثل:
READ_COMMITTED_SNAPSHOT
كما يدعم:
SNAPSHOT
مع تفعيل الإعداد المناسب. citeturn0search0
PostgreSQL
الـ default:
READ COMMITTED
ويعتمد على MVCC.
وفي PostgreSQL:
READ UNCOMMITTED
يُعامل عمليًا مثل:
READ COMMITTED
كما أن SERIALIZABLE يمكن أن ينهي transaction بـ serialization failure عندما يكتشف conflict يحتاج retry. citeturn0search3
MySQL InnoDB
الـ default:
REPEATABLE READ
وInnoDB يستخدم MVCC بالإضافة إلى locking strategies مختلفة، ومنها gap/next-key locking في حالات معينة. citeturn0search1
Oracle
Oracle لديها implementation مختلفة للـ transaction consistency والـ read consistency، ولذلك لا ينفع تحفظ behavior من SQL Server وتفترض إنه مطابق في Oracle.
🏦 المثال البنكي الصحيح
خلينا نرجع للسؤال الأساسي:
Balance = 1000
وفي نفس الوقت:
A → Transfer 800
B → Transfer 800
مش الحل ببساطة:
if (balance >= 800)
{
balance -= 800;
}
لأن:
READ
↓
CHECK
↓
WRITE
ممكن تتداخل.
✅ Pattern أفضل: Atomic Conditional Update
في حالات كثيرة تقدر تخلي قاعدة البيانات نفسها تنفذ القرار بشكل ذري:
UPDATE Accounts
SET Balance = Balance - 800
WHERE Id = @AccountId
AND Balance >= 800;
ثم تشوف:
Rows affected = 1
يعني:
Transfer allowed
أو:
Rows affected = 0
يعني:
Insufficient balance
وده ممتاز لأنه يقلل race بين:
SELECT balance
و:
UPDATE balance
لكن التحويل البنكي الكامل ما زال يحتاج Transaction إذا عندك عمليات مرتبطة لازم تنجح معًا:
Debit
Credit
Ledger Entry
Audit
...
🔐 Pessimistic Locking
ممكن transaction تمسك الحساب وتمنع التعديلات المتعارضة:
BEGIN
↓
Lock Account
↓
Read Balance
↓
Check
↓
Debit
↓
Commit
Transaction الثانية:
WAIT
ثم بعد انتهاء الأولى:
Read new balance
وتقرر إذا كان فيه رصيد كافي.
مفيد لما:
Contention high
Correctness critical
Conflict expensive
لكن:
Blocking
Deadlocks
Lower concurrency
لازم تتحسب.
🧠 Optimistic Concurrency
بدل ما تقفل row من البداية.
تقرأ:
Balance = 1000
Version = 7
وتعمل update:
UPDATE Accounts
SET Balance = @NewBalance,
Version = Version + 1
WHERE Id = @Id
AND Version = 7;
لو:
Rows affected = 1
نجحت.
لو:
Rows affected = 0
يبقى حد سبقك وغير البيانات.
فتعمل:
Conflict
→ Retry / Reject
حسب business requirement.
وده مناسب في أنظمة كثيرة لما contention مش دائمًا عالي.
⚠️ Transaction مش معناها "المشكلة اتحلت"
دي أهم جملة في البوست.
غلط:
I used transaction.
Therefore concurrency is safe.
صح:
I used a transaction
+
I understand isolation
+
I protect the critical invariant
+
I handle conflicts
💀 Deadlocks
مثال:
Transaction A
locks Account 1
↓
needs Account 2
Transaction B
locks Account 2
↓
needs Account 1
فتبقى:
A waits for B
B waits for A
Database تكتشف الـ cycle.
وتضطر تعمل rollback لإحدى العمليات.
عشان كده application لازم يكون مستعد أحيانًا لـ:
Deadlock
Serialization Failure
Transient Concurrency Error
والـ retry لازم يكون:
Controlled
Bounded
Idempotent
مش:
Retry forever 😂
🧭 اختيار Isolation Level
متسألش:
"إيه أفضل Isolation Level؟"
اسأل:
"إيه الـ invariant أو concurrency problem اللي أنا بحاول أحميها؟"
مثلاً:
CRUD عادي
غالبًا:
READ COMMITTED
مناسب كبداية، حسب الـ DBMS والـ workload.
Read-heavy system
ممكن تستفيد من:
MVCC
RCSI
Snapshot
حسب database.
Financial / critical invariant
ممكن تحتاج:
Atomic updates
Explicit locks
Optimistic concurrency
Serializable
أو combination مناسب.
مش معنى "Banking" إنك لازم تحط SERIALIZABLE على كل query في النظام.
⚠️ ملحوظات مهمة
1. Transaction قصيرة أفضل
ما تعملش:
BEGIN TRANSACTION
Call external API
Wait 5 seconds
Send Email
Process Image
...
COMMIT
ده ممكن يطول عمر الـ locks/version retention ويزود contention.
الأفضل غالبًا:
Validate
↓
Short DB Transaction
↓
Commit
↓
External work
مع تصميم مناسب للـ consistency.
2. مش كل حاجة تتحل بـ Isolation
أحيانًا الحل الأفضل:
UNIQUE Constraint
CHECK Constraint
Atomic UPDATE
Optimistic Concurrency
Explicit Lock
حسب المشكلة.
3. MVCC مش معناه "مفيش Locks"
أنظمة MVCC قد تستخدم locks أيضًا في writes أو locking reads أو لحماية أجزاء أخرى من النظام.
MVCC وLocks مش دائمًا بدائل exclusive لبعض.
4. Snapshot مش معناه إن كل المشاكل اختفت
Snapshot isolation يحل مشاكل قراءة كثيرة.
لكن بعض business invariants عبر عدة rows ممكن تحتاج:
Serializable
Explicit Locking
Constraints
Application-level coordination
5. Isolation Level هو Contract
هو بيحدد:
What can I observe?
What concurrency effects are allowed?
لكن:
How is it implemented?
دي مسؤولية الـ DBMS.
🧮 مقارنة سريعة
| Isolation | Dirty Read | Non-Repeatable | Phantom | Concurrency |
|---|---|---|---|---|
| Read Uncommitted | ممكن | ممكن | ممكن | أعلى عادةً |
| Read Committed | لا | ممكن | ممكن | جيدة |
| Repeatable Read | لا | لا | حسب DBMS/implementation | أقل |
| Serializable | لا | لا | لا | أقل عادةً |
| Snapshot | لا | لا | لا داخل snapshot semantics | جيدة للقراءات |
الجدول تبسيطي؛ الـ exact semantics والتنفيذ يختلفان حسب DBMS.
SQL Server وPostgreSQL وMySQL لا ينفذون هذه المستويات بنفس الطريقة. citeturn0search0turn0search1turn0search3
🎯 إجابة انترفيو جاهزة
لو الـ interviewer سألك:
"عندي حساب فيه 1000، واتنين حاولوا يحولوا 800 في نفس الوقت. تعمل إيه؟"
ممكن تجاوب:
"المشكلة هنا Race Condition في عملية read-modify-write. مش كفاية أعمل
if balance >= amountداخل application code، لأن الاتنين ممكن يقرأوا نفس الرصيد. محتاج أحمي الـ invariant داخل الـ database، مثل atomic conditional update أو locking أو optimistic concurrency، حسب الـ workload."
ثم:
"ولو التحويل نفسه عبارة عن أكثر من عملية، زي debit وcredit وledger entry، هحط العمليات المرتبطة داخل transaction واحدة عشان أضمن atomicity."
ولو سألك:
"هل Transaction وحدها تحل المشكلة؟"
الإجابة:
"لا. Transaction بتضمن atomicity، لكن الـ concurrency behavior يعتمد على isolation level وطريقة تنفيذ العملية. لازم أفهم Dirty Reads وLost Updates وNon-Repeatable Reads وPhantom Reads، وأختار concurrency strategy مناسبة."
ولو سألك:
"إيه الفرق بين Read Committed وSerializable؟"
تقول:
"
READ COMMITTEDيمنع قراءة البيانات غير committed، لكنه يسمح ببعض التغيرات بين القراءات.SERIALIZABLEيوفر isolation أقوى ويجعل concurrent execution مكافئًا للـ serial execution من ناحية النتائج المقبولة، لكن تكلفته أعلى وقد يسبب blocking أو serialization failures حسب الـ DBMS."
ولو سألك:
"Locks ولا MVCC؟"
تقول:
"مش اختيار binary. كثير من قواعد البيانات تستخدم الاثنين بدرجات مختلفة. Locks مفيدة لحماية التعديلات والتنسيق، وMVCC/row versioning يسمح بقراءات أكثر concurrency بدون blocking بنفس الطريقة. الاختيار يعتمد على الـ DBMS والـ workload."
🧠 الخلاصة
المشكلة الحقيقية مش:
Can I update a row?
المشكلة:
What happens when 1,000 people update it at the same time?
لازم تفكر في:
Transactions
↓
Atomicity
↓
Isolation
↓
Concurrency Control
↓
Locks / MVCC
↓
Isolation Levels
↓
Business Invariants
↓
Conflict Handling
والمهندس الشاطر مش اللي حافظ:
Read Committed
Repeatable Read
Serializable
لكن اللي لما يشوف:
1000 concurrent users
يسأل:
What can race?
What must remain true?
What can be stale?
What can block?
What happens on conflict?
What happens on retry?
What happens if the process crashes?
What does my database actually guarantee?
لأن أغلب مشاكل الـ Production الخطيرة مش بتحصل لما مستخدم واحد يستخدم النظام.
بتظهر لما:
ألف مستخدم يضغطوا نفس الزرار في نفس الثانية.
وده بالضبط الفرق بين:
CRUD Developer
و:
Software Engineer 🧠
📚 مصادر رسمية
Microsoft SQL Server
- Transaction Locking and Row Versioning Guide citeturn0search0
PostgreSQL
- Concurrency Control / MVCC citeturn0search2
- Transaction Isolation citeturn0search3
MySQL InnoDB
- Transaction Isolation Levels citeturn0search1
Oracle
<div align="center">
☕ Transaction مش مجرد BEGIN و COMMIT
هي طريقة تتحكم بيها في الحقيقة لما أكتر من عملية تحاول تغيّرها في نفس اللحظة.
Concurrency is where "working code" becomes engineering.
</div>منشورات مقترحة
مشاريع ذات صلة

واجهة متجر إلكتروني متجاوبة مبنية بـ Next.js و React لتصفح الأجهزة التقنية وإدارة السلة ومراحل الشراء.