Kiểm soát tương tranh dựa trên khóa
Việc sử dụng khóa để kiểm soát quyền truy cập vào các tài nguyên được chia sẻ dễ bị bế tắc và một mình bộ lập lịch giao dịch không thể ngăn chặn sự xuất hiện của chúng.
Ví dụ, các hệ thống cơ sở dữ liệu quan hệ sử dụng các khóa khác nhau để đảm bảo các thuộc tính ACID giao dịch .
Cho dù bạn đang sử dụng hệ thống cơ sở dữ liệu quan hệ nào, các khóa sẽ luôn được lấy khi sửa đổi (ví dụ: UPDATE
hoặc DELETE
) một bản ghi bảng nhất định. Nếu không khóa một hàng đã được sửa đổi bởi một giao dịch hiện đang chạy, Atomicity sẽ bị xâm phạm .
Bế tắc là gì
Như tôi đã giải thích trong bài viết này , một sự bế tắc xảy ra khi hai giao dịch đồng thời không thể đạt được tiến bộ bởi vì mỗi giao dịch chờ người kia phát hành khóa, như được minh họa trong sơ đồ sau.
Bởi vì cả hai giao dịch đang trong giai đoạn mua lại khóa, không ai phát hành khóa trước khi có được giao dịch tiếp theo.
Phục hồi từ một tình huống bế tắc
Nếu bạn đang sử dụng thuật toán Kiểm soát tương tranh dựa trên các khóa, thì luôn có nguy cơ chạy trong tình huống bế tắc. Bế tắc có thể xảy ra trong bất kỳ môi trường đồng thời, không chỉ trong một hệ thống cơ sở dữ liệu.
Chẳng hạn, một chương trình đa luồng có thể bế tắc nếu hai hoặc nhiều luồng đang chờ trên các khóa đã được mua trước đó để không có luồng nào có thể thực hiện bất kỳ tiến trình nào. Nếu điều này xảy ra trong một ứng dụng Java, JVM không thể buộc Thread phải dừng thực thi và giải phóng các khóa của nó.
Ngay cả khi Thread
lớp phơi bày một stop
phương thức, phương thức đó đã bị từ chối kể từ Java 1.1 vì nó có thể khiến các đối tượng bị bỏ lại ở trạng thái không nhất quán sau khi một luồng bị dừng. Thay vào đó, Java định nghĩa một interrupt
phương thức, hoạt động như một gợi ý như một luồng bị gián đoạn có thể chỉ cần bỏ qua sự gián đoạn và tiếp tục thực hiện nó.
Vì lý do này, một ứng dụng Java không thể phục hồi sau tình huống bế tắc và nhà phát triển ứng dụng có trách nhiệm phải ra lệnh cho các yêu cầu mua lại khóa theo cách mà các khóa chết không bao giờ có thể xảy ra.
Tuy nhiên, một hệ thống cơ sở dữ liệu không thể thực thi một lệnh mua lại khóa nhất định vì không thể thấy trước những khóa nào khác mà một giao dịch nhất định sẽ muốn có thêm. Giữ nguyên trật tự khóa trở thành trách nhiệm của lớp truy cập dữ liệu và cơ sở dữ liệu chỉ có thể hỗ trợ khôi phục từ tình huống bế tắc.
Công cụ cơ sở dữ liệu chạy một quy trình riêng biệt để quét biểu đồ xung đột hiện tại cho các chu kỳ chờ khóa (nguyên nhân là do các khóa chết). Khi một chu kỳ được phát hiện, công cụ cơ sở dữ liệu chọn một giao dịch và hủy bỏ nó, khiến các khóa của nó được giải phóng, để giao dịch kia có thể đạt được tiến bộ.
Không giống như JVM, một giao dịch cơ sở dữ liệu được thiết kế như một đơn vị công việc nguyên tử. Do đó, một rollback rời khỏi cơ sở dữ liệu ở trạng thái nhất quán.
Để biết thêm chi tiết về chủ đề này, hãy xem bài viết này là tốt.