關於資料庫層面上鎖,解決程式併發插入多條重複資料

2021-08-08 18:21:18 字數 1421 閱讀 9165

在資料庫層面上樂觀鎖對於update那個是很簡單的,無非在設計表的時候新增乙個字段,如:version 這個字段用來記錄更新的次數,只加不減,就是用來防止程式多次更新某條資料,然後出現問題。  舉個例子吧,對自己的理解也有幫助。 比如某一張表 有id,name,status,version  一共四個字段,假設這是訂單表,其中訂單表有 未發貨、已發貨、已簽收、拒發貨這四個狀態。有2個管理員,同時操作某個使用者,乙個是操作為已發貨,乙個是操作未拒發貨。這時候程式是不管的,就按照先後順序直接執行一遍。這時雙方都是互相不知道對方做了什麼操作,都以為自己操作成功了。但是肯定是有乙個管理員得到結果不是自己想要的,那麼這個時候是不是應該出現提示,說訂單狀態已經被改變了,然後最後操作的那個管理員需要確認後才能進行操作。那麼如何避免呢?這時候就需要用上version了。 假設初始化的時候version是1。在做了一次update操作後version的次數就變成2了。那麼version也是要成為where的條件之一。

update table set status='已發貨',version = version+1 where version=1

當時2個管理員看到的肯定是version為1的資料,那麼他們同時操作,update安裝這個寫的話就只有第乙個管理員會操作成功了。因為第二次操作的時候version已經變成2了。當然這只是乙個很小的例子。實際情況實際考慮,解決方法應該是和這個類似的。

可是我今天遇到是insert,這時候就懵逼了,怎麼解決呢?由於我們這個業務的特殊性,乙個使用者一條最多只能搖一次,那麼也就是說insert每天最多執行一次。

我們正好有個資料的createdate,那麼可以利用起這個字段,條件是今日是否已經插入了一條

insert into `table` (createdate,欄位2,欄位3,欄位4,user_id)

select now(),值2,值3,值4,#

from dual where not exists(

select * from `table` where date(createdate) = date(now()) and

user_id = #

)

這樣就可以避免同一使用者,一天能夠插入2條資料的尷尬情況。個人認為這個是很好的利用了資料庫的原子性(不知道這樣說會不會有問題)。sql執行語句的時候是嚴格按照先後順序來的,只有前一條執行完成了,然後這個時候才執行下一條。正是利用了關係型資料的這個特點,才能在資料庫層面解決一些併發問題。對資料的改動基本就是insert和update,只不過insert在插入的時候順便查了一遍是否已經存在類似的資料罷了。這樣就完美解決了這個bug。也不知道有沒有其他的解決方法。

引用zyyr365的一段筆記吧:

使用 dual

做表名可以讓你在 select 語句後面直接跟上要插入欄位的值,即使這些值還不存在當前表中。

高併發大資料資料庫層面的處理

三種併發策略 1.什麼都不做,任由併發產生,以最終提交結果為準。2.開放式併發,衝突產生時,告訴使用者當前資源被占用。3.保守式併發,強制加鎖,只有當前使用者更新提交完畢才能被下乙個使用者占用。保守式併發 保守式併發通常用於兩個目的。第一,在某些情況下,存在對相同記錄的大量爭用。在資料上放置鎖所費的...

資料庫鎖解決併發問題

問題描述 乙個優惠券活動,使用者可以領取優惠券,但是乙個優惠券活動領取數量有限制,所以使用者在領取的時候就需要先統計一下以領用的優惠券數量。然後在生成這張優惠券領取記錄。那麼此時就會出現併發問題,當多個使用者領取同乙個優惠券活動的時候,他們統計的優惠券已領數量小於限定可領取數量,所以都可以執行生成 ...

資料庫高併發解決方法總結

資料庫高併發解決方法總結 2017年01月23日 10 33 23 乙個專案剛開始的時候是為了實現基本功能,隨著版本和功能的迭代,大資料和高併發成了軟體設計必須考慮的問題 本質很簡單,乙個是慢,乙個是等。兩者是相互關聯的,因為慢,所以要等,因為等,所以慢,解決了慢,也就解決了等,解決了等,也就解決了...