第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

Django:如何防止數(shù)據(jù)庫(kù)條目的并發(fā)修改

Django:如何防止數(shù)據(jù)庫(kù)條目的并發(fā)修改

月關(guān)寶盒 2019-11-06 10:37:20
是否存在防止兩個(gè)或多個(gè)用戶(hù)同時(shí)修改同一數(shù)據(jù)庫(kù)條目的方法?向用戶(hù)顯示執(zhí)行第二次提交/保存操作的錯(cuò)誤消息是可以接受的,但是數(shù)據(jù)不應(yīng)被靜默覆蓋。我認(rèn)為鎖定項(xiàng)目不是一個(gè)選項(xiàng),用戶(hù)可以使用“后退”按鈕或干脆關(guān)閉其瀏覽器,留下了鎖,直到永遠(yuǎn)。
查看完整描述

3 回答

?
繁星淼淼

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊

這是我做樂(lè)觀鎖在Django:


updated = Entry.objects.filter(Q(id=e.id) && Q(version=e.version))\

          .update(updated_field=new_value, version=e.version+1)

if not updated:

    raise ConcurrentModificationException()

上面列出的代碼可以作為Custom Manager中的方法實(shí)現(xiàn)。


我做出以下假設(shè):


filter()。update()將導(dǎo)致單個(gè)數(shù)據(jù)庫(kù)查詢(xún),因?yàn)閒ilter是惰性的

數(shù)據(jù)庫(kù)查詢(xún)是原子的

這些假設(shè)足以確保之前沒(méi)有其他人更新過(guò)該條目。如果以這種方式更新了多行,則應(yīng)使用事務(wù)。


警告 Django Doc:


請(qǐng)注意,update()方法直接轉(zhuǎn)換為SQL語(yǔ)句。這是直接更新的批量操作。它不會(huì)對(duì)你的模型運(yùn)行任何save()方法,或發(fā)出pre_save或post_save信號(hào)


查看完整回答
反對(duì) 回復(fù) 2019-11-06
?
慕森王

TA貢獻(xiàn)1777條經(jīng)驗(yàn) 獲得超3個(gè)贊

這個(gè)問(wèn)題有點(diǎn)老了,我的回答有點(diǎn)晚了,但是在我理解之后,在Django 1.4中使用以下命令解決了這個(gè)問(wèn)題:


select_for_update(nowait=True)

看文檔


返回一個(gè)查詢(xún)集,該查詢(xún)集將鎖定行直到事務(wù)結(jié)束,從而在支持的數(shù)據(jù)庫(kù)上生成SELECT ... FOR UPDATE SQL語(yǔ)句。


通常,如果另一個(gè)事務(wù)已經(jīng)獲取了所選行之一的鎖,則查詢(xún)將阻塞,直到釋放該鎖為止。如果這不是您想要的行為,請(qǐng)調(diào)用select_for_update(nowait = True)。這將使呼叫成為非阻塞。如果另一個(gè)事務(wù)已經(jīng)獲取了沖突的鎖,則在評(píng)估查詢(xún)集時(shí)將引發(fā)DatabaseError。


當(dāng)然,這僅在后端支持“選擇更新”功能時(shí)才起作用,例如sqlite不支持。不幸的是:nowait=TrueMySql不支持:您必須在其中使用:nowait=False,它只會(huì)在釋放鎖之前阻塞。


查看完整回答
反對(duì) 回復(fù) 2019-11-06
?
有只小跳蛙

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超8個(gè)贊

實(shí)際上,事務(wù)在這里無(wú)濟(jì)于事...除非您希望使事務(wù)運(yùn)行在多個(gè)HTTP請(qǐng)求上(您可能不希望這樣做)。


在這些情況下,我們通常使用的是“樂(lè)觀鎖定”。據(jù)我所知,Django ORM不支持該功能。但是,已經(jīng)有一些關(guān)于添加此功能的討論。


所以你自己一個(gè)人?;旧希鷳?yīng)該做的是在模型中添加一個(gè)“版本”字段,并將其作為隱藏字段傳遞給用戶(hù)。更新的正常周期為:


讀取數(shù)據(jù)并將其顯示給用戶(hù)

用戶(hù)修改數(shù)據(jù)

用戶(hù)發(fā)布數(shù)據(jù)

該應(yīng)用程序?qū)⑵浔4婊財(cái)?shù)據(jù)庫(kù)中。

為了實(shí)現(xiàn)樂(lè)觀鎖定,在保存數(shù)據(jù)時(shí),您需要檢查從用戶(hù)那里獲得的版本是否與數(shù)據(jù)庫(kù)中的版本相同,然后更新數(shù)據(jù)庫(kù)并遞增版本。如果不是,則表示自加載數(shù)據(jù)以來(lái)發(fā)生了更改。


您可以通過(guò)單個(gè)SQL調(diào)用來(lái)實(shí)現(xiàn),例如:


UPDATE ... WHERE version = 'version_from_user';

僅當(dāng)版本相同時(shí),此調(diào)用才會(huì)更新數(shù)據(jù)庫(kù)。


查看完整回答
反對(duì) 回復(fù) 2019-11-06
  • 3 回答
  • 0 關(guān)注
  • 1023 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)