2013-06-17 50 views
5

Các Django documentation khẳng định rằng:select_for_update trong phát triển Django

Nếu bạn dựa trên “các giao dịch tự động” để cung cấp khóa giữa select_for_update() và một hoạt động viết tiếp theo - một thiết kế cực kỳ mỏng manh, nhưng dù sao có thể - bạn phải quấn mã có liên quan trong atomic().

Lý do tại sao điều này không còn hoạt động nữa là tự động được thực hiện ở lớp cơ sở dữ liệu chứ không phải lớp ứng dụng? Trước giao dịch would be held open until a data-altering function is called:

hành vi mặc định của Django là để chạy với một giao dịch mở mà nó cam kết tự động khi bất kỳ built-in, mô hình dữ liệu làm thay đổi hàm được gọi

Và kể từ Django 1.6, với autcommit tại lớp cơ sở dữ liệu, rằng một select_for_update theo sau là ví dụ một write thực sự sẽ chạy trong hai giao dịch? Nếu trường hợp này xảy ra, thì không phải select_for_update trở thành vô dụng vì điểm của nó là lock the rows until a data altering function was called?

+0

Tự động chuyển đổi ở lớp cơ sở dữ liệu đi kèm với django 1.6, không phải 1.5. – fabspro

+0

@fabspro cảm ơn - sửa chữa – Taras

Trả lời

5

select_for_update sẽ chỉ khóa hàng đã chọn trong ngữ cảnh của một giao dịch duy nhất. Nếu bạn đang sử dụng autocommit, nó sẽ không làm những gì bạn nghĩ rằng nó, bởi vì mỗi truy vấn sẽ có hiệu quả là giao dịch riêng của mình (bao gồm truy vấn SELECT ... FOR UPDATE). Bọc chế độ xem của bạn (hoặc chức năng khác) trong transaction.atomic và nó sẽ thực hiện chính xác những gì bạn đang mong đợi.

+0

Đó là những gì tôi nghĩ tài liệu đang nói, nhưng nếu điều đó đúng, điều đó có khiến chức năng select_for_update khá vô ích (vì lý do ban đầu của nó là khóa các hàng bị ảnh hưởng cho đến khi thao tác ghi được thực hiện) – Taras

+2

@ Taras - 'select_for_update' thực hiện chính xác như nó được làm tài liệu, nhưng nếu bạn sử dụng nó với autocommit, về cơ bản bạn sẽ nhận được và giải phóng khóa tất cả cùng một lúc, điều đó không giúp được gì nhiều. Vì vậy, các truy vấn hoạt động tất cả như nhau, nhưng không có một giao dịch để duy trì một loại trạng thái, làm thế nào Postgres sẽ biết khi nào để phát hành khóa (khác hơn là ngay lập tức)? Nếu nó chỉ giữ chúng cho đến khi viết, hãy tưởng tượng một chương trình xấu đã chọn một loạt các hàng để cập nhật và sau đó đặt ra một ngoại lệ. Các hàng đã chọn sẽ bị khóa vĩnh viễn. – orokusaki

+0

Tôi nghĩ bây giờ tôi đã hiểu. 'select_for_update' không hữu ích với autocommit, nhưng nó ** là ** có ích khi hành vi tự động không được sử dụng, ví dụ: khi giao dịch được xác định rõ ràng thông qua câu lệnh' nguyên tử' ..? – Taras

Các vấn đề liên quan