2 回答

TA貢獻(xiàn)1712條經(jīng)驗(yàn) 獲得超3個(gè)贊
是的,我認(rèn)為這種情況transaction.atomic()
并不像您期望的那樣工作。
要了解它的作用,您必須了解 SQL 的事務(wù)隔離級(jí)別以及它們所保證的確切行為。你沒有提到你正在使用什么數(shù)據(jù)庫(kù),但是 PostgreSQL 有很好的關(guān)于這個(gè)主題的文檔。
您的期望似乎是它會(huì)像隔離級(jí)別一樣工作SERIALIZABLE
。事實(shí)上,Django 中默認(rèn)的隔離級(jí)別是READ COMMITTED
. 在那個(gè)隔離級(jí)別下,如果你有兩個(gè)這樣的事務(wù)同時(shí)運(yùn)行,它們都會(huì)被likes_num
相同的數(shù)字覆蓋。
一種解決方案是使用 F 對(duì)象而不是設(shè)置likes_num
為特定值。在這種情況下,新值將基于寫入時(shí)字段中的任何值,而不是讀取行時(shí)字段中的值。
entry.likes_num = F('likes_num') + 1
另一種解決方案是使用select_for_update()
,它將鎖定entry
行。如果可以的話,最好避免使用鎖,所以我會(huì)選擇 F-object 版本。

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超9個(gè)贊
我認(rèn)為您需要使用 F 對(duì)象
from django.db.models import F
...
entry.likes_num = F('likes_num') + 1
entry.save()
因?yàn)槟诖a執(zhí)行中沒有任何錯(cuò)誤,并且兩個(gè)事務(wù)是有效的。
添加回答
舉報(bào)