MongoDB Transactions trong Node.js: Đừng Để Dữ Liệu Rơi Rụng!
Lê Lân
1
MongoDB Transactions trong Node.js — Hướng Dẫn Toàn Diện cùng Mongoose
Mở Đầu
Bạn có nghĩ MongoDB không phù hợp cho những thao tác phức tạp, nhiều bước giống như giao dịch (transaction) trong SQL? Hãy suy nghĩ lại! Với replica sets và sharded clusters, MongoDB hỗ trợ các giao dịch tuân thủ ACID, giúp đảm bảo tính toàn vẹn dữ liệu trong các hệ thống đa tác vụ.
Trong bài viết này, chúng ta sẽ cùng khám phá cách sử dụng giao dịch MongoDB trong một backend Node.js thực tế, sử dụng thư viện phổ biến Mongoose. Bạn sẽ hiểu khi nào cần dùng transaction, cách thiết lập, và một ví dụ chuyển tiền giữa hai ví dụ đơn giản nhưng thực tế. Đồng thời, tôi sẽ chia sẻ những lưu ý về các lỗi thường gặp và cách xử lý khi giao dịch gặp sự cố.
Khi Nào Cần Dùng Transactions?
Multi-Document Atomicity Là Gì?
MongoDB đảm bảo tính phi nguyên tử (atomic) ngay trong phạm vi một document duy nhất — tức là mọi thay đổi trên một document sẽ được thực hiện cùng lúc hoặc không thực hiện gì cả.
Tuy nhiên, khi bạn cần thực hiện thao tác ảnh hưởng tới nhiều documents hoặc collections cùng lúc, như:
Trừ tiền ở user A và cộng tiền cho user B.
Cập nhật nhiều collections cùng một lúc, ví dụ orders và inventory.
Đảm bảo dữ liệu chỉ thay đổi khi toàn bộ thao tác thành công; nếu có lỗi, rollback toàn bộ thay đổi.
Khi đó, bạn cần đến transactions để đảm bảo toàn bộ các thao tác được thực thi như một khối, tránh trường hợp chỉ một phần thao tác thành công gây ra lỗi đồng bộ dữ liệu.
MongoDB chỉ hỗ trợ transaction trên đa document khi đang chạy trên replica set hoặc sharded cluster. Nếu bạn chạy trên standalone server, giao dịch sẽ không hoạt động.
Thiết Lập Môi Trường với Mongoose
1. Cài đặt Mongoose
Bạn cần sẵn sàng môi trường Node.js đã cài đặt npm. Chạy lệnh sau để cài mongoose:
Hint: Luôn chạy thử các transaction trong môi trường Replica Set để đảm bảo chúng hoạt động đúng.
Các Lỗi Thường Gặp Khi Dùng Transactions
Lỗi
Giải thích
Khắc phục
Không dùng Replica Set
MongoDB standalone không hỗ trợ transaction
Chuyển sang môi trường Replica Set
Quên truyền session
Không gán
{ session }
trong các thao tác truy vấn, lưu dữ liệu
Đảm bảo session được truyền đầy đủ
Giao dịch lâu, quá tải
Transaction chậm, gây giảm hiệu suất
Giữ transaction ngắn gọn, tránh thao tác nặng
Transactions trong MongoDB không phải là phương án lý tưởng cho workloads có throughput cực cao, hãy cân nhắc sử dụng nó cho những phần logic cần thiết.
Mẫu Retry Khi Giao Dịch Bị Lỗi Tạm Thời
Trong môi trường thực tế, transaction có thể bị thất bại do lỗi mạng hoặc lỗi tạm thời. Bạn nên:
Wrap toàn bộ giao dịch trong vòng lặp retry với exponential backoff.
Phân biệt lỗi TransientTransactionError hoặc UnknownTransactionCommitResult để tự động thử lại.
Đây là cách để nâng cao độ bền vững cho logic nghiệp vụ.
Tổng Kết (TL;DR)
Dùng transaction khi bạn cần đảm bảo tính nhất quán trong thao tác trên nhiều document/collections.
Luôn bọc code trong session.startTransaction(), commit hoặc abort transaction phù hợp.
Giữ transaction ngắn và đơn giản.
Sử dụng retry pattern khi cần tăng độ ổn định.
MongoDB transactions yêu cầu môi trường Replica Set hoặc Sharded Cluster để hoạt động.
Sử dụng đúng transactions có thể giúp phòng tránh lỗi dữ liệu nghiêm trọng trong backend Node.js của bạn, nâng cao chất lượng hệ thống.