I. Khái niệm Transaction
Có rất nhiều trường hợp mà bạn cần phải thay đổi dữ liệu trong một hoặc nhiều bảng cơ sở dữ liệu. Trong một số tình huống dữ liệu có thể không nhất quán khi các thực thi lệnh riêng lẻ. Nếu câu lệnh đầu tiên được thực hiện một cách chính xác nhưng các câu lệnh tiếp theo thất bại thì dữ liệu có thể ở trạng thái không chính xác.
Có rất nhiều trường hợp mà bạn cần phải thay đổi dữ liệu trong một hoặc nhiều bảng cơ sở dữ liệu. Trong một số tình huống dữ liệu có thể không nhất quán khi các thực thi lệnh riêng lẻ. Nếu câu lệnh đầu tiên được thực hiện một cách chính xác nhưng các câu lệnh tiếp theo thất bại thì dữ liệu có thể ở trạng thái không chính xác.
Một ví dụ điển hình là chức năng chuyển số dư tài khoản của một hệ thống ngân hàng. A chuyển giao có thể yêu cầu 2 câu lệnh UPDATE và INSERT. Đầu tiên phải tăng số dư của tài khoản đích sau đó làm giảm số dư tài khoản thứ hai. Cuối cùng sẽ chèn 1 hàng mới vào trong bảng chuyển giao để cung cấp nhật ký của việc giao dịch này.
Nếu việc tăng số dư thực hiện chính xác nhưng việc thứ 2 và thứ 3 thất bại thì số dư của 1 tài khoản sẽ được tăng lên nhưng tài khoản nguồn sẽ không thay đổi và sẽ không có nhật ký để ghi lại vấn đề này.
Trong tình huống như vậy, chúng ta cần một cách để đảm bảo rằng tất cả các lệnh liên quan thực hiện chính xác trước khi thay đổi cơ sở dữ liệu. Chúng ta cũng cần để có thể đảo ngược tất cả các lệnh thực thi nếu có một thay đổi thất bại. Điều này đạt được bằng cách sử dụng các giao dịch (transaction).
Giao dịch là một nhóm các câu lệnh SQL có thứ tự các hoạt động thao tác trên cơ sở dữ liệu nhưng được xem như một đơn vị thao tác duy nhất và chúng chỉ có thể cùng nhau thành công hoặc cùng nhau thất bại.
Một giao dịch không được xem là thành công khi chỉ cần một thao tác đơn giản nào đó trong nó không hoàn thành. Trường hợp này được xem là thất bại.
Các giao dịch được bắt đầu trước khi dữ liệu thay đổi và cam kết một khi tất cả các bản cập nhật liên quan được thực hiện thành công. Cho đến khi giao dịch được cam kết, những thay đổi không được lưu trữ trong cơ sở dữ liệu. Tại bất kỳ thời điểm nào trong giao dịch, bạn có thể rollback (thao tác lùi cơ sở dữ liệu về một trạng thái cũ.) để kết thúc giao dịch.
Trong các ứng dụng truy cập cơ sở dữ liệu, nhiều người dùng có thể đồng thời xem và sửa dữ liệu. Các thao tác đồng thời có thể dẫn đến dữ liệu không nhất quán và chính xác. Bên cạnh đảm bảo hoạt động đúng của một tập hợp các câu lệnh SQL, một giao dịch cần đảm bảo người dùng khác không thể sửa chữa các dòng liên quan đến giao dịch.
II. Thuộc tính của giao dịch
Một giao dịch có 4 thuộc tính then chốt (không thể thiếu) được viết tắt là ACID
Atomicity (Tính nguyên tố)
Đảm bảo tất cả các hành động trong một đơn vị giao dịch là thành công hoàn toàn. Ngược lại giao dịch sẽ bị dừng ngay tại thời điểm bị lỗi.
Tất nhiên các hoạt động trước trong giao dịch đó sẽ quay lại đúng trạng thái cũ của nó. Chẳng hạn việc chuyển tiền có thể thành công hay trục trặc vì nhiều lý do nhưng tính nguyên tố bảo đảm rằng một tài khoản sẽ không bị trừ tiền nếu như tài khoản kia chưa được cộng số tiền tương ứng.
Consistency(Tính nhất quán)
Đảm bảo cơ sở dữ liệu được thay đổi đúng trạng thái sau khi giao dịch thành công và không xảy ra lỗi.
Isolation(Tính cô lập)
Đảm bảo giao dịch này hoạt động độc lập so với giao dịch khác.
Durability(Tính bền vững)
Đảm bảo kết quả hoặc tác động của giao dịch vẫn luôn tồn tại, kể cả khi hệ thống xảy ra lỗi.
III. Khi nào thì sử dụng Giao dịch
Giao dịch được dùng khi xử lý các vấn đề liên quan đến truy xuất dữ liệu đồng thời để đảm bảo tính toàn vẹn dữ liệu khi xảy ra sự thay đổi (các hành động như INSERT, UPDATE, DELETE…).
Khi một giao dịch bao gồm nhiều lệnh cập nhật, nó đảm bảo tất cả các cập nhật đều được thực hiện thành công, hoặc trong trường hợp một lệnh gặp sự cố toàn bộ transaction bị hủy bỏ. Khi đó dữ liệu trở về trạng thái như trước khi xảy ra transaction.
Nói cách khác giao dịch ngăn chặn tình huống dữ liệu được cập nhật nửa chừng, trong đó một phần được cập nhật còn một phần bị bỏ qua.
IV. Mức độ cô lập (isolation level) giữa các giao dịch
Các giao dịch có thể đồng thời truy cập đến dữ liệu chia sẻ. . Tùy thuộc vào mức độ cô lập giữa các giao dịch có thể xuất hiện các hiện tượng.
Dirty reads
Xảy ra khi một giao dịch được cho phép đọc dữ liệu từ một dòng đang bị sửa chữa bởi một giao dịch khác chưa committed.
Nonrepeatable reads
Có thể xảy ra với các trường hợp sau.
1 Giao dịch A đọc 1 bảng
2 Sau đó giao dịch B cập nhật bảng đó
3 Sau đó giao dịch B cập nhật bảng đó
4 Giao dịch A đọc lại bảng sau khi giao dịch B cập nhật
5 Giao dịch A thấy dữ liệu lấy ra không giống ban đầu
Phantom reads
Xảy ra khi trong một giao dịch , hai câu truy vấn giống nhau khi thi hành trả lại tập hợp các dòng khác nhau. Điều này xảy ra khi tại thời điểm giữa hai câu truy vấn đó, giao dịch thứ hai thêm vào các dòng dữ liệu mới thỏa mãn mệnh đề WHERE của câu truy vấn.
V. Thao tác giao dịch cơ bản trong MySQL
1. Tạo một giao dịch.
START TRANSACTION;
BEGIN;
Có thể thực hiện nhiều câu lệnh SELECT, INSERT, UPDATE, DELETE sau lệnh BEGIN;
2. Kết thúc giao dịch
COMMIT, ROLLBACK
1. Lệnh COMMIT lưu các thay đổi vào cơ sở dữ liệu.
2. Lệnh ROLLBACK hủy các thay đổi thực hiện trong giao dịch và cơ sở dữ liệu được phục hồi về trạng thái trước giao dịch.
SAVEPOINT định nghĩa một điểm đánh dấu trong một giao dịch.
ROLLBACK TO SAVEPOINT cho phép phục hồi lại trước điểm đánh dấu