Hiểu rõ hơn về Transaction trong Rails
Bài đăng này đã không được cập nhật trong 6 năm
Hi cả nhà, thời gian gần đây đang làm một dự án và đụng phải 1 task xử lý deadlock(hy vọng là sẽ có thời gian để viết nhiều hơn về vấn đề này). Mình chọn cách dùng transaction để xử lý, do đó cũng bỏ ra khá nhiều thời gian để tìm hiểu về lý thuyết, hy vọng rằng với bài viết này mình có thể giúp các bạn hiểu rõ hơn về transaction và các mức isolation của nó, thay vì chỉ dùng và nắm 1 số mức quen thuộc.
1. Transaction trong SQL là gì ?
Transaction trong SQL là một đơn vị công việc được thực hiện bởi một Database. Transaction là đơn vị hoặc dãy công việc được thực hiện theo một thứ tự logic và hợp lý, có thể được thao tác bởi người dùng hoặc bởi một Database program.
Một transaction tạo ra một hoặc nhiều thay đổi tới Database. Ví dụ, nếu bạn đang tạo một bản ghi hoặc cập nhật một bản ghi hoặc xóa một bản ghi từ một bảng, thì bạn đang thực hiện transaction trên bảng đó. Nên việc điều khiển các transaction là rất quan trọng cho việc bảo đảm toàn vẹn dữ liệu và để xử lý các Database Error.
Thực tế, bạn sẽ tập hợp nhiều truy vấn SQL vào trong một nhóm và sẽ thực thi tất cả truy vấn này cùng với nhau như là một phần của một transaction.
Và về cơ bản thì transaction mà chúng ta dùng trong rails(được rails support) vẫn có đầy đủ các đặc tính của transaction sql bình thường, nên trong phạm vi bài viết, mình sẽ ưu tiên xem xét dưới góc độ sql - như vậy cũng sẽ giúp chúng ta hiểu về transaction trong rails hơn
2. Các thuộc tính của Transaction
-
Atomicity: bảo đảm rằng tất cả hoạt động bên trong đơn vị công việc được hoàn thành một cách thành công; nếu không, transaction bị ngừng ở điểm thất bại, và các hoạt động trước được trao trả về trạng thái trước đó.
-
Consistency: bảo đảm rằng Database thay đổi một cách chính xác trạng thái theo một transaction đã được commit thành công.
-
Isolation: cho các transaction khả năng hoạt động một cách độc lập và không liên quan đến nhau.
-
Durability: bảo đảm rằng kết quả hoặc tác động của một transaction, mà đã được commit, vẫn còn tồn tại trong trường hợp hệ thống thất bại.
3. Các điều khiển transaction trong SQL
Trong SQL, có các lệnh sau được sử dụng để điều khiển transaction:
-
COMMIT: để lưu các thay đổi.
-
ROLLBACK: để quay trở lại trạng thái trước khi có thay đổi.
-
SAVEPOINT: tạo các điểm (point) bên trong các nhóm transaction để ROLLBACK, tức là để quay trở lại điểm trạng thái đó.
-
SET TRANSACTION: đặt một tên cho một transaction.
Các lệnh điều khiển transaction chỉ được sử dụng với các lệnh INSERT, UPDATE và DELETE. Chúng không thể được sử dụng trong khi tạo và xóa bảng, bởi vì những hoạt động này được ký thác tự động trong Database.
4. Tìm hiểu sâu về các mức isolation được cung cấp trong rails
-
read_uncommitted: Khi transaction thực hiện ở mức này, các truy vấn vẫn có thể truy nhập vào các bản ghi đang được cập nhật bởi một transaction khác và nhận được dữ liệu tại thời điểm đó mặc dù dữ liệu đó chưa được commit (uncommited data). Nếu vì lý do nào đó transaction ban đầu rollback lại những cập nhật, dữ liệu sẽ trở lại giá trị cũ. Khi đó transaction thứ hai nhận được dữ liệu sai.
-
read_committed: Transaction sẽ không đọc được dữ liệu đang được cập nhật mà phải đợi đến khi việc cập nhật thực hiện xong. Vì thế nó tránh được dirty read như ở mức trên.
-
repeatable_read: Mức isolation này hoạt động nhứ mức read commit nhưng nâng thêm một nấc nữa bằng cách ngăn không cho transaction ghi vào dữ liệu đang được đọc bởi một transaction khác cho đến khi transaction khác đó hoàn tất.
-
serializable: Mức isolation này tăng thêm một cấp nữa và khóa toàn bộ dải các bản ghi có thể bị ảnh hưởng bởi một transaction khác, dù là UPDATE/DELETE bản ghi đã có hay INSERT bản ghi mới. Nếu bạn thay cửa sổ 1 bằng đoạn code
5. Phạm vi áp dụng các mức isolation
Mức Isolation | Dirty read | Nonrepeatable read | Phantom read |
---|---|---|---|
read_uncommitted | Yes | Yes | Yes |
read_committed | No | Yes | Yes |
repeatable_read | No | No | Yes |
serializable | No | No | No |
All rights reserved