Khóa (Locks) là một phần không thể thiếu để duy trì kiểm soát đồng thời (concurrency control) trong DBMS. Một giao dịch (transaction) trong bất kỳ hệ thống nào triển khai kiểm soát đồng thời dựa trên khóa không thể đọc hoặc ghi một câu lệnh cho đến khi nó đã获得所需的锁.
Có hai loại khóa trong các giao thức dựa trên khóa:
- Khóa nhị phân (Binary Locks) – Chỉ có thể ở một trong hai trạng thái: khóa (locked) hoặc mở khóa (unlocked).
- Khóa chia sẻ/Độc quyền (Shared/Exclusive Locks) – Khóa chia sẻ (Shared locks) được lấy khi chỉ thực hiện thao tác đọc (read). Khóa chia sẻ có thể chia sẻ giữa nhiều giao dịch vì không có dữ liệu bị thay đổi. Khóa độc quyền (Exclusive locks) được dùng khi thực hiện thao tác ghi (write). Chỉ giao dịch nắm giữ khóa độc quyền mới được phép thay đổi giá trị dữ liệu.
Các giao thức khóa khác nhau:
Giao thức khóa đơn giản (Simplistic Lock Protocol)
Một khóa được lấy bởi giao dịch trên giá trị dữ liệu trước khi thao tác ghi được thực hiện. Sau thao tác ghi, khóa có thể được giải phóng. Ví dụ Simplistic Lock Protocol:
| T1 | T2 |
|---|---|
| R(A) | |
| R(A) | |
| Lock(B) | |
| R(B) | |
| W(B) | |
| Unlock(B) | |
| Lock(C) | |
| R(C) | |
| W(C) | |
| Unlock(C) | |
| Commit | |
| Commit |
Có hai giao dịch T1 và T2 như trên. Không cần khóa cho thao tác đọc nhưng trước thao tác ghi, mỗi giao dịch lấy khóa và giải phóng sau đó.
Giao thức khóa hai giai đoạn (Two-Phase Locking Protocol)
Giao thức khóa hai giai đoạn có hai giai đoạn: giai đoạn mở rộng (growing) và giai đoạn thu hẹp (shrinking). Giao dịch chỉ có thể lấy khóa khi ở giai đoạn mở rộng. Khi vào giai đoạn thu hẹp, nó có thể giải phóng các khóa đã lấy trước đó nhưng không thể lấy khóa mới. Khóa độc quyền được ký hiệu bằng X và khóa chia sẻ bằng S. Ví dụ Two-phase locking protocol:
| T1 | T2 |
|---|---|
| S(A) | |
| R(A) | |
| S(A) | |
| R(A) | |
| X(B) | |
| R(B) | |
| W(B) | |
| X(C) | |
| R(C) | |
| W(C) | |
| Unlock(C) | |
| Unlock(A) | |
| Unlock(B) | |
| Unlock(A) | |
| Commit | |
| Commit |
Trong ví dụ trên, T1 và T2 chia sẻ biến A bằng khóa chia sẻ vì chỉ thao tác đọc trên A. T1 lấy khóa độc quyền trên B cho thao tác ghi và giải phóng ngay sau. T2 làm tương tự với C.
Giao thức khóa hai giai đoạn nghiêm ngặt (Strict Two-Phase Locking Protocol)
Giao thức khóa hai giai đoạn nghiêm ngặt tương tự giao thức khóa hai giai đoạn. Sự khác biệt duy nhất là trong giao thức 2PL nghiêm ngặt, tất cả các khóa độc quyền lấy bởi giao thức cần được giữ cho đến khi giao thức commit hoặc abort. Ví dụ Strict two-phase locking protocol:
| T1 | T2 |
|---|---|
| S(A) | |
| R(A) | |
| S(A) | |
| R(A) | |
| X(B) | |
| R(B) | |
| W(B) | |
| X(C) | |
| R(C) | |
| W(C) | |
| Unlock(A) | |
| Unlock(A) | |
| Commit | |
| Unlock(B) | |
| Commit | |
| Unlock(C) |
Trong ví dụ trên, T1 và T2 chia sẻ biến A bằng khóa chia sẻ vì chỉ thao tác đọc trên A. T1 lấy khóa độc quyền trên B cho thao tác ghi và T2 làm tương tự với C. Khóa độc quyền chỉ được giải phóng sau khi giao dịch đã commit. Tuy nhiên, không có giới hạn như vậy cho khóa chia sẻ.
Giao thức khóa hai giai đoạn chặt chẽ (Rigorous two-phase locking protocol)
Giao thức khóa hai giai đoạn chặt chẽ chỉ là mở rộng của giao thức khóa hai giai đoạn và giao thức khóa hai giai đoạn nghiêm ngặt. Ở đây, tất cả các khóa do một giao dịch giữ, dù chia sẻ hay độc quyền, chỉ được giải phóng sau khi giao dịch commit hoặc abort. Ví dụ Rigorous two-phase locking protocol:
| T1 | T2 |
|---|---|
| S(A) | |
| R(A) | |
| S(A) | |
| R(A) | |
| X(B) | |
| R(B) | |
| W(B) | |
| X(C) | |
| R(C) | |
| W(C) | |
| Commit | |
| Unlock(A) | |
| Unlock(B) | |
| Commit | |
| Unlock(A) | |
| Unlock(C) |
Trong ví dụ trên, T1 và T2 chia sẻ biến A bằng khóa chia sẻ vì chỉ thao tác đọc trên A. T1 lấy khóa độc quyền trên B cho thao tác ghi và T2 làm tương tự với C. Cả khóa chia sẻ và khóa độc quyền chỉ được giải phóng sau khi các giao dịch đã commit.