2011-08-11 7 views
6

Setup:Force django cam kết

  • Python script Một chèn dữ liệu vào một DB mỗi 15 phút
  • Python script B truy vấn một vài trong số các mục mới nhất từ ​​DB mỗi vài phút

Cả hai đều sử dụng ORM của django, chạy trên cùng một máy và sử dụng một DB cục bộ của MySQL.

Vấn đề:
B lấy về mục, ngoại trừ một mới nhất, mặc dù Một lưu nó phút trước.

Tôi nghi ngờ rằng A không đóng giao dịch, do đó B xem DB mà không có mục nhập cuối cùng. Thật vậy khi kiểm tra các bản ghi MySQL, tôi nhận thấy commit cho mỗi INSERT xảy ra ngay trước tiếp theoINSERT.

Mặc dù nó được cho là không cần thiết, tôi đã thêm @commit_on_success trang trí vào Chức năng bao gồm save(), nhưng không hiệu quả.

Làm cách nào để buộc django (hoặc MySQL ?!) cam kết ngay sau save()?

UPDATE:
tôi phát hiện ra rằng các cam kết DO xảy ra - Tôi đã hiểu sai lệch để tin rằng họ làm không phải vì MySQL's General Query Log only has 1 sec resolution.
Trong điều kiện này và thông tin mới khác, tôi đã reasked câu hỏi here.

Trả lời

9

Bạn có thể sử dụng trình trang trí commit_manually và gọi nó bất cứ khi nào bạn muốn.

Straight từ documentation:

from django.db import transaction 

@transaction.commit_manually 
def viewfunc(request): 
    ... 
    # You can commit/rollback however and whenever you want 
    transaction.commit() 
    ... 

    # But you've got to remember to do it yourself! 
    try: 
     ... 
    except: 
     transaction.rollback() 
    else: 
     transaction.commit() 

này trả lời các câu hỏi mà bạn hỏi, mặc dù tôi tự hỏi, nếu có thể có cái gì khác tại nơi làm việc.

+0

Điều này khác với '@ commit_on_success' như thế nào? (chuyển sang cam kết thủ công sẽ làm tổn thương thời gian hoạt động của chúng tôi, vì vậy tôi muốn hiểu rõ hơn trước khi ủ với hệ thống) – Jonathan

+0

'commit_on_success' chỉ chạy cam kết sau khi hàm trả về được bọc; nếu nó ngồi nhàn rỗi mà không trả lại nó sẽ không giúp được gì. 'commit_manually' cho phép bạn gọi cam kết ngay sau lần lưu cuối cùng. Tôi không chắc mã của bạn đang làm gì, vì vậy đó là tất cả những gì tôi có thể nghĩ đến ngay bây giờ. – eric

+0

Mặc dù tôi phát hiện ra vấn đề của mình là ở nơi khác, tôi tin rằng câu trả lời của bạn là quan trọng đối với những người tìm kiếm buộc cam kết django, do đó tôi đánh dấu nó là câu trả lời đúng – Jonathan

0

Vấn đề là do MySQL theo mặc định có mức cô lập giao dịch REPEATABLE-READ. Điều đó có nghĩa là cùng một truy vấn được mong đợi sẽ trả về cùng một giá trị. Thay đổi sẽ không trở lại. Bạn có thể làm hai việc ở đây:

  1. Đặt mức cách ly giao dịch thành ĐÃ ĐỌC trong cài đặt. Như được giải thích here.
  2. Buộc thực hiện cam kết, do đó đóng giao dịch trên tập lệnh B, do đó, khi giao dịch mới bắt đầu, bạn sẽ thấy tất cả thay đổi trước giao dịch mới này.Model.objects.update() mẹo này