從sql語句的角度解刨SqlServer插入語句的併發問題

今天收到一個小學弟的求助,數據庫插入偶爾重複,怎麼在sql語句上進行解決。


 

Q:學長,我導入excel數據的操作,平時使用好好的,怎麼突然發生插入重複的問題?

A:你是使用哪個ORM框架進行操作的?

 

Q:什麼是ORM框架?

A:額……,你數據庫怎麼鏈接操作的?

 

Q:我使用Connection對象進行鏈接操作的。

A:哦,ADO.NET呀,你把導入數據的插入sql語句的截圖發出來看看。

 

Q:sql截圖(這裏就不展示了,就是一個簡單的insert into,如:INSERT INTO aTable(id) VALUES("1"))

A:哦哦,你語句沒有併發情況下沒問題,但是多人同時導入數據就存在併發,數據重複意料之中。

 

Q:啊,這還涉及到併發?那我怎麼修改呀

A:簡單,不改變其他操作的情況下,你把插入語句加事務加鎖機制既可以了。

 

Q:額……不怎麼懂,有demo嗎?

A:沒事,我就在你的sql語句上優化下,你直接粘貼就可以了。

 


 

我們來解刨一下這個問題,現在很多人依賴ORM,都沒怎麼寫sql了,我們就從sql的角度解析一下這個問題。

這裏不好提供代碼展示,我們這裏就簡單進行一個模擬還原使用場景。

創建一個表,命名爲aTable,裏面就一個字段id,int類型,然後插入一個數據爲1;

 

操作一:重現問題出現原因

然後同時(有點間隔也沒關係,但隔時間要小)在查詢分析器的兩個窗口中執行下如下語句:

declare @id int
set @id = ( select max(id) from aTable )
while @id < 40000
 begin
 set @id = @id + 1
 insert into aTable ( id ) select @id
 set @id = ( select max(id) from aTable ) 
 end

這樣的目的在於測試當兩個用戶同時操作同一個表時的重複性操作,模擬多用戶同時導入相同的excel數據,

結果:共得到42953條數據,其中2953條重複,當然,這個重複數據跟執行間隔時間有關。


 

操作二:進行第一步優化,添加事務

 sql語句加上事務處理,

然後同時(有點間隔也沒關係,但間隔時間要小)在查詢分析器的兩個窗口中執行下如下語句:

begin tran  --開啓事務

declare @id int
set @id = ( select max(id) from aTable )
while @id < 40000
 begin
 set @id = @id + 1
 insert into aTable ( id ) select @id
 set @id = ( select max(id) from aTable ) 
 end

commit tran  --提交事務

結果:共得到40000條數據,無重複,但是執行時間是沒加事務處理時的6倍,時間太久。


 

操作三:進行第二步優化,添加鎖

 sql語句加上事務處理和鎖機制,

然後同時(有點間隔也沒關係,但間隔時間要小)在查詢分析器的兩個窗口中執行下如下語句:

begin tran --開始事務

declare @id INT
set @id = ( select max(id) from aTable )
while @id < 40000
begin
set @id = @id + 1
--添加鎖 with(tablock)
insert into aTable with (tablock) ( id ) select @id
set @id = ( select max(id) from aTable )
end

commit tran --提交事務

結果:共得到40000條數據,無重複,執行時間快。


 

這樣就從sql上簡單解決併發問題啦,當然,還有其他問題和解決方法,

這裏就不做敘說了,具體情況遇到再分析,拜拜。

 

歡迎關注訂閱我的微信公衆平臺【熊澤有話說】,更多好玩易學知識等你來取
作者:熊澤-學習中的苦與樂
公衆號:熊澤有話說
出處:  https://www.cnblogs.com/xiongze520/p/14524707.html
創作不易,轉載或者部分轉載、摘錄,請在文章明顯位置註明作者和原文鏈接。  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章