# ACID & Database Transactions for .NET Backend Engineers
Khi làm backend, nhiều lỗi nghiêm trọng không đến từ syntax hay framework mà đến từ **transaction boundary** không đúng. Một flow tưởng đơn giản như chuyển tiền, redeem coupon hoặc cập nhật wallet có thể làm dữ liệu sai nếu transaction không được thiết kế đúng.
## ACID là gì?
ACID gồm bốn thuộc tính cốt lõi của transaction:
### Atomicity
Một transaction phải **thành công toàn bộ hoặc rollback toàn bộ**.
“`sql
BEGIN TRY
BEGIN TRANSACTION;
UPDATE Accounts
SET Balance = Balance – 100
WHERE Id = 1;
UPDATE Accounts
SET Balance = Balance + 100
WHERE Id = 2;
COMMIT;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK;
THROW;
END CATCH;
“`
Nếu bước thứ hai lỗi thì bước đầu tiên cũng phải rollback.
### Consistency
Database phải chuyển từ một trạng thái hợp lệ sang một trạng thái hợp lệ khác.
“`sql
ALTER TABLE Accounts
ADD CONSTRAINT CK_Accounts_Balance
CHECK (Balance >= 0);
“`
Consistency thường được bảo vệ bằng:
– Primary Key
– Foreign Key
– Unique Constraint
– Check Constraint
– Business rules
– Transaction logic
### Isolation
Isolation kiểm soát cách các transaction chạy đồng thời nhìn thấy và thay đổi dữ liệu của nhau.
Các vấn đề thường gặp:
– Dirty Read
– Non-repeatable Read
– Phantom Read
– Lost Update
### Durability
Sau khi transaction đã `COMMIT`, dữ liệu phải tồn tại kể cả khi process hoặc server gặp sự cố.
SQL Server sử dụng transaction log để hỗ trợ recovery.
## Transaction trong EF Core
Một lần gọi:
“`csharp
await dbContext.SaveChangesAsync();
“`
thường được EF Core thực hiện trong một transaction khi cần.
Nếu business flow gồm nhiều bước độc lập nhưng phải thành công cùng nhau:
“`csharp
await using var transaction =
await dbContext.Database.BeginTransactionAsync();
try
{
dbContext.Wallets.Update(wallet);
await dbContext.SaveChangesAsync();
dbContext.UserCoupons.Add(coupon);
await dbContext.SaveChangesAsync();
await transaction.CommitAsync();
}
catch
{
await transaction.RollbackAsync();
throw;
}
“`
## Khi nào cần explicit transaction?
Ví dụ:
“`text
Update Wallet
+ Create Coupon
+ Write Reward History
“`
Nếu ba bước phải thành công hoặc thất bại cùng nhau, chúng nên nằm trong cùng transaction.
Không nên giữ transaction mở khi:
“`text
Call external API
Send email
Wait for third-party service
Long-running computation
“`
Transaction càng dài thì lock càng lâu, blocking tăng và nguy cơ deadlock cao hơn.
## Database transaction không phải distributed transaction
Ví dụ:
“`text
Save Order in SQL
+
Publish message to Azure Service Bus
“`
Database có thể commit thành công nhưng publish message lại thất bại.
Kết quả:
“`text
Order exists
Message missing
“`
Đây là lý do các hệ thống distributed thường sử dụng pattern như **Transactional Outbox**.
## Interview questions
### What is ACID?
> ACID stands for Atomicity, Consistency, Isolation, and Durability. Atomicity ensures that a transaction either fully succeeds or fully rolls back. Consistency keeps the database in a valid state. Isolation controls how concurrent transactions interact. Durability ensures committed data survives failures.
### When would you use an explicit transaction in EF Core?
> I use an explicit transaction when multiple SaveChanges calls or related database operations must succeed or fail as one business operation.
## Key takeaways
– ACID là nền tảng của transaction reliability.
– Transaction boundary phải bám theo business operation.
– Giữ transaction ngắn.
– Database transaction không tự giải quyết consistency giữa database và message broker.
**Next:** Part 2 — Isolation Levels & Concurrency