簡體   English   中英

從另一個進程保存對象時,在Model.objects.filter()之后需要Django transaction.commit()

[英]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_manuallyfilter()調用正下方的transaction.commit()行之后,我確實從該字段獲取了更新的值(該值是從其他進程保存的)。

有什么理由需要這樣做嗎? 在實際上根本不更新模型的函數上使用transaction.commit()有什么影響/潛在問題? 我不確定為什么它能起作用,如果它有意義,那么希望其他人會遇到這個問題。

謝謝,

由於您正在使用事務中間件,因此每個請求都會獲得一個不同的事務。

在Web請求中處理事務的推薦方法是通過Django的TransactionMiddleware將它們綁定到請求和響應階段。

它的工作方式如下:當請求啟動時,Django啟動事務。 如果產生的響應沒有問題,則Django會提交所有未決的事務。 如果view函數產生異常,則Django回滾所有未決的事務。

這意味着,如果第二個進程的請求在觸發寫入之前進入,則其事務將早於寫入。 然后,數據庫將做正確的事情,並報告創建第二個進程的事務時的當前值。 在讀取之前手動提交第二個進程的事務是無害的(只要它沒有進行任何編輯),並告訴數據庫創建一個新事務。 它將后寫,並因此為您提供修改的結果。

我也遇到了這個問題。 Django緩存查詢結果(這對於單個進程而言是一件好事)。 如果第二個進程具有相同查詢的緩存,則在刷新緩存之前,它將看不到更新。

由於某種原因, transaction.commit()刷新緩存,因此有助於解決此問題。 在運行查詢之前立即調用該方法,您應該直接從數據庫中看到結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM