[英]Django transaction.commit() needed after Model.objects.filter() when object was saved from another process
我有兩個運行Django代碼庫的進程,由於各種原因,一個進程將更新一個對象,如下所示:
myObj.aField = "updated"
myObj.save()
然后,另一個過程嘗試讀取該對象,如下所示:
def getObj(xxx):
objs = TheModel.objects.filter(xyz=xxx)
for obj in objs:
print obj.aField
從第二個過程讀取值時,我看不到更新后的值,而是看到了舊值。 第二次運行該函數時,我確實看到了更改。
我已經注意到,如果從第二個過程(一次閱讀)中,我按如下所示更改了函數,則會得到更新后的值:
@transaction.commit_manually
def getObj(xxx):
objs = TheModel.objects.filter(xyz=xxx)
transaction.commit()
for obj in objs:
print obj.aField
在添加裝飾器@transaction.commit_manually
和filter()
調用正下方的transaction.commit()
行之后,我確實從該字段獲取了更新的值(該值是從其他進程保存的)。
有什么理由需要這樣做嗎? 在實際上根本不更新模型的函數上使用transaction.commit()
有什么影響/潛在問題? 我不確定為什么它能起作用,如果它有意義,那么希望其他人會遇到這個問題。
謝謝,
由於您正在使用事務中間件,因此每個請求都會獲得一個不同的事務。
在Web請求中處理事務的推薦方法是通過Django的TransactionMiddleware將它們綁定到請求和響應階段。
它的工作方式如下:當請求啟動時,Django啟動事務。 如果產生的響應沒有問題,則Django會提交所有未決的事務。 如果view函數產生異常,則Django回滾所有未決的事務。
這意味着,如果第二個進程的請求在觸發寫入之前進入,則其事務將早於寫入。 然后,數據庫將做正確的事情,並報告創建第二個進程的事務時的當前值。 在讀取之前手動提交第二個進程的事務是無害的(只要它沒有進行任何編輯),並告訴數據庫創建一個新事務。 它將后寫,並因此為您提供修改的結果。
我也遇到了這個問題。 Django緩存查詢結果(這對於單個進程而言是一件好事)。 如果第二個進程具有相同查詢的緩存,則在刷新緩存之前,它將看不到更新。
由於某種原因, transaction.commit()
刷新緩存,因此有助於解決此問題。 在運行查詢之前立即調用該方法,您應該直接從數據庫中看到結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.