# Optimistic vs Pessimistic Concurrency in EF Core
Giả sử coupon chỉ còn:
“`text
Stock = 1
“`
User A và User B cùng đọc `1`. Nếu cả hai cùng redeem thành công, business invariant đã bị phá vỡ.
Đây là bài toán concurrency.
## Optimistic Concurrency
Optimistic concurrency giả định conflict xảy ra không thường xuyên.
Ví dụ:
“`text
Version = 5
“`
Update:
“`sql
UPDATE Events
SET Status = @status,
Version = Version + 1
WHERE Id = @id
AND Version = 5;
“`
Nếu:
“`text
0 rows affected
“`
nghĩa là data có thể đã bị thay đổi bởi transaction khác.
## EF Core Concurrency Token
Ví dụ:
“`csharp
public class Event
{
public Guid Id { get; set; }
public string Status { get; set; }
[Timestamp]
public byte[] RowVersion { get; set; }
}
“`
Khi conflict xảy ra EF Core có thể throw:
“`text
DbUpdateConcurrencyException
“`
## Không nên catch rồi ignore
Các strategy phổ biến:
### Client Wins
Overwrite database bằng data client.
### Database Wins
Bỏ thay đổi client và reload database state.
### Merge
So sánh các field và merge theo business rule.
Strategy nào đúng phụ thuộc business requirement.
## Pessimistic Concurrency
Pessimistic locking giả định conflict có khả năng cao.
Concept:
“`text
Lock first
Work
Commit
Release
“`
Ưu điểm:
– ngăn một số race conditions từ đầu
Nhược điểm:
– blocking
– deadlock
– throughput thấp hơn
## Optimistic vs Pessimistic
| | Optimistic | Pessimistic |
|—|—|—|
| Lock lâu | Không | Có |
| Throughput | Cao | Thấp hơn |
| Conflict handling | Sau khi xảy ra | Ngăn từ đầu |
| Phù hợp | Conflict hiếm | Conflict cao |
## Case: Last Coupon
Giả sử:
“`text
Stock = 1
“`
Hai user cùng redeem.
Một cách an toàn là atomic conditional update:
“`sql
UPDATE Coupons
SET Stock = Stock – 1
WHERE Id = @id
AND Stock > 0;
“`
Sau đó kiểm tra affected rows.
Nếu một row bị update:
“`text
success
“`
Nếu zero rows:
“`text
out of stock / already consumed
“`
## Interview questions
### Optimistic vs pessimistic concurrency?
> Optimistic concurrency allows transactions to proceed without long-lived locks and detects conflicts when updating. Pessimistic concurrency locks resources upfront to prevent conflicts but can cause blocking and deadlocks.
### What do you do with DbUpdateConcurrencyException?
> I don’t blindly ignore it. I determine whether the business operation can be retried, whether database state should win, or whether the conflict needs to be returned to the user.
## Key takeaways
Concurrency control không phải framework detail. Nó là business correctness problem.
Khi thiết kế một operation concurrent, hãy hỏi:
“`text
What invariant must never be broken?
“`
Sau đó chọn:
“`text
Atomic SQL operation
Optimistic concurrency
Pessimistic locking
Unique constraint
Isolation level
“`
phù hợp với invariant đó.
**End of Stage 1 — Database Fundamentals**