校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > SQL Server并發處理存在就更新解決方案探討

SQL Server并發處理存在就更新解決方案探討

熱門標簽:優質地圖標注 武漢長沙外呼系統方法和技巧 外呼系統電銷專用 怎樣在地圖上標注路線圖標 百度地圖標注不同路線 千呼電銷機器人價格 京華物流公司地圖標注 奧威地圖標注多個地方 智能語音外呼系統選哪家

前言

本節我們來講講并發中最常見的情況存在即更新,在并發中若未存在行記錄則插入,此時未處理好極容易出現插入重復鍵情況,本文我們來介紹對并發中存在就更新行記錄的七種方案并且我們來綜合分析最合適的解決方案。

探討存在就更新七種方案

首先我們來創建測試表

IF OBJECT_ID('Test') IS NOT NULL
 DROP TABLE Test

CREATE TABLE Test
(
 Id int,
 Name nchar(100),
 [Counter] int,primary key (Id),
 unique (Name)
);
GO

解決方案一(開啟事務)

我們統一創建存儲過程通過來SQLQueryStress來測試并發情況,我們來看第一種情況。

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 
 BEGIN TRANSACTION
 IF EXISTS ( SELECT 1
    FROM Test
    WHERE Id = @Id )
  UPDATE Test
  SET  [Counter] = [Counter] + 1
  WHERE Id = @Id;
 ELSE
  INSERT Test
    ( Id, Name, [Counter] )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO

同時開啟100個線程和200個線程出現插入重復鍵的幾率比較少還是存在。

解決方案二(降低隔離級別為最低隔離級別UNCOMMITED)

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 
 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
 BEGIN TRANSACTION
 IF EXISTS ( SELECT 1
    FROM Test
    WHERE Id = @Id )
  UPDATE Test
  SET  [Counter] = [Counter] + 1
  WHERE Id = @Id;
 ELSE
  INSERT Test
    ( Id, Name, [Counter] )
  VALUES ( @Id, @name, 1 );
 COMMIT
GO

此時問題依舊和解決方案一無異(如果降低級別為最低隔離級別,如果行記錄為空,前一事務如果未進行提交,當前事務也能讀取到該行記錄為空,如果當前事務插入進去并進行提交,此時前一事務再進行提交此時就會出現插入重復鍵問題)

解決方案三(提升隔離級別為最高級別SERIALIZABLE)

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 
 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
 BEGIN TRANSACTION
 IF EXISTS ( SELECT 1
    FROM dbo.Test
    WHERE Id = @Id )
  UPDATE dbo.Test
  SET  [Counter] = [Counter] + 1
  WHERE Id = @Id;
 ELSE
  INSERT dbo.Test
    ( Id, Name, [Counter] )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO

在這種情況下更加糟糕,直接到會導致死鎖

此時將隔離級別提升為最高隔離級別會解決插入重復鍵問題,但是對于更新來獲取排它鎖而未提交,而此時另外一個進程進行查詢獲取共享鎖此時將造成進程間相互阻塞從而造成死鎖,所以從此知最高隔離級別有時候能夠解決并發問題但是也會帶來死鎖問題。

解決方案四(提升隔離級別+良好的鎖)

此時我們再來在添加最高隔離級別的基礎上增添更新鎖,如下:

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 
 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
 BEGIN TRANSACTION
 IF EXISTS ( SELECT 1
    FROM dbo.Test WITH(UPDLOCK)
    WHERE Id = @Id )
  UPDATE dbo.Test
  SET  [Counter] = [Counter] + 1
  WHERE Id = @Id;
 ELSE
  INSERT dbo.Test
    ( Id, Name, [Counter] )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO

運行多次均未發現出現什么異常,通過查詢數據時使用更新鎖而非共享鎖,這樣的話一來可以讀取數據但不阻塞其他事務,二來還確保自上次讀取數據后數據未被更改,這樣就解決了死鎖問題。貌似這樣的方案是可行得,如果是高并發不知是否可行。

解決方案五(提升隔離級別為行版本控制SNAPSHOT)

ALTER DATABASE UpsertTestDatabase
SET ALLOW_SNAPSHOT_ISOLATION ON
 
ALTER DATABASE UpsertTestDatabase
SET READ_COMMITTED_SNAPSHOT ON
GO 

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 
 BEGIN TRANSACTION
 IF EXISTS ( SELECT 1
    FROM dbo.Test
    WHERE Id = @Id )
  UPDATE dbo.Test
  SET  [Counter] = [Counter] + 1
  WHERE Id = @Id;
 ELSE
  INSERT dbo.Test
    ( Id, Name, [Counter] )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO

上述解決方案也會出現插入重復鍵問題不可取。

解決方案六(提升隔離級別+表變量)

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 DECLARE @updated TABLE ( i INT );
 
 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
 BEGIN TRANSACTION
 UPDATE Test
 SET  [Counter] = [Counter] + 1
 OUTPUT DELETED.Id
   INTO @updated
 WHERE Id = @Id;
 
 IF NOT EXISTS ( SELECT i
     FROM @updated )
  INSERT INTO Test
    ( Id, Name, counter )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO

經過多次認證也是零錯誤,貌似通過表變量形式實現可行。

解決方案七(提升隔離級別+Merge)

通過Merge關鍵來實現存在即更新否則則插入,同時我們應該注意設置隔離級別為SERIALIZABLE否則會出現插入重復鍵問題,代碼如下:

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 SET TRAN ISOLATION LEVEL SERIALIZABLE 
 BEGIN TRANSACTION
 MERGE Test AS [target]
 USING
  ( SELECT @Id AS Id
  ) AS source
 ON source.Id = [target].Id
 WHEN MATCHED THEN
  UPDATE SET
    [Counter] = [target].[Counter] + 1
 WHEN NOT MATCHED THEN
  INSERT ( Id, Name, [Counter] )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO

多次認證無論是并發100個線程還是并發200個線程依然沒有異常信息。

總結

本節我們詳細討論了在并發中如何處理存在即更新,否則即插入問題的解決方案,目前來講以上三種方案可行。

解決方案一(最高隔離級別 + 更新鎖)

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 
 BEGIN TRANSACTION;
 
 UPDATE dbo.Test WITH ( UPDLOCK, HOLDLOCK )
 SET  [Counter] = [Counter] + 1
 WHERE Id = @Id;
 
 IF ( @@ROWCOUNT = 0 )
  BEGIN
   INSERT dbo.Test
     ( Id, Name, [Counter] )
   VALUES ( @Id, @Name, 1 );
  END
 
 COMMIT
GO

暫時只能想到這三種解決方案,個人比較推薦方案一和方案三, 請問您有何高見,請留下您的評論若可行,我將進行后續補充。

解決方案二(最高隔離級別 + 表變量)

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 DECLARE @updated TABLE ( i INT );
 
 SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
 BEGIN TRANSACTION
 UPDATE Test
 SET  [Counter] = [Counter] + 1
 OUTPUT DELETED.id
   INTO @updated
 WHERE id = @id;
 
 IF NOT EXISTS ( SELECT i
     FROM @updated )
  INSERT INTO Test
    ( Id, Name, counter )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO


解決方案三(最高隔離級別 + Merge)

IF OBJECT_ID('TestPro') IS NOT NULL
 DROP PROCEDURE TestPro;
GO
 
CREATE PROCEDURE TestPro ( @Id INT )
AS
 DECLARE @Name NCHAR(100) = CAST(@Id AS NCHAR(100))
 SET TRAN ISOLATION LEVEL SERIALIZABLE 
 BEGIN TRANSACTION
 MERGE Test AS [target]
 USING
  ( SELECT @Id AS Id
  ) AS source
 ON source.Id = [target].Id
 WHEN MATCHED THEN
  UPDATE SET
    [Counter] = [target].[Counter] + 1
 WHEN NOT MATCHED THEN
  INSERT ( Id, Name, [Counter] )
  VALUES ( @Id, @Name, 1 );
 COMMIT
GO

暫時只能想到這三種解決方案,個人比較推薦方案一和方案三, 請問您有何高見,請留下您的評論若可行,我將進行后續補充。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • mysql如果數據不存在,則插入新數據,否則更新的實現方法
  • mysql 存在該記錄則更新,不存在則插入記錄的sql
  • mysql 記錄不存在時插入 記錄存在則更新的實現方法

標簽:宿州 七臺河 天水 防疫戰設 益陽 威海 來賓 銅仁

巨人網絡通訊聲明:本文標題《SQL Server并發處理存在就更新解決方案探討》,本文關鍵詞  SQL,Server,并發,處理,存在,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《SQL Server并發處理存在就更新解決方案探討》相關的同類信息!
  • 本頁收集關于SQL Server并發處理存在就更新解決方案探討的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    欧美性受极品xxxx喷水| 韩国av一区二区三区在线观看| 久久欧美中文字幕| 欧美不卡视频一区| 婷婷国产在线综合| 高清国产午夜精品久久久久久| 亚洲图片自拍偷拍| 六月丁香综合在线视频| 日韩激情一二三区| 精品一区二区三区的国产在线播放| 奇米影视一区二区三区小说| 国产一区二三区好的| 粉嫩久久99精品久久久久久夜| 99国产精品视频免费观看| 在线视频中文字幕一区二区| 欧美女孩性生活视频| 精品久久久久av影院| 中文字幕免费不卡| 亚洲午夜精品一区二区三区他趣| 天堂av在线一区| 国产成人亚洲精品青草天美| 91麻豆福利精品推荐| 69堂国产成人免费视频| 欧美视频日韩视频在线观看| 偷窥少妇高潮呻吟av久久免费| 日韩免费高清电影| 91伊人久久大香线蕉| 欧美色网站导航| 日韩午夜在线影院| 国产精品久久久久久久久免费丝袜 | 久久精品欧美一区二区三区不卡| 亚洲国产激情av| 午夜精品爽啪视频| 国产馆精品极品| 欧美日韩精品一区二区| 久久女同互慰一区二区三区| 欧美精品一区二区不卡| 不卡的看片网站| 日韩视频123| 欧美一级夜夜爽| 久久国产精品第一页| 自拍偷自拍亚洲精品播放| 日韩国产欧美三级| 91麻豆精品一区二区三区| 日韩亚洲欧美中文三级| 亚洲乱码国产乱码精品精可以看| 另类专区欧美蜜桃臀第一页| 成人一道本在线| 欧美一级二级在线观看| 一区二区三区日韩| 高清久久久久久| 亚洲精品在线三区| 亚洲成人av福利| 色狠狠桃花综合| 国产精品久久久久久久第一福利| 久久久久国产精品厨房| 爽好久久久欧美精品| 亚洲大片在线观看| 在线观看亚洲一区| 91成人免费网站| 中文字幕一区二区三区在线观看| 免费观看日韩av| 欧美日韩另类一区| 亚洲国产精品久久一线不卡| 成人精品在线视频观看| 精品盗摄一区二区三区| 蜜桃传媒麻豆第一区在线观看| 欧美日韩不卡一区| 亚洲一区电影777| 91丨九色丨蝌蚪丨老版| 中日韩av电影| yourporn久久国产精品| 国产精品成人午夜| 色综合中文综合网| 欧美大片在线观看一区| 日韩国产欧美在线观看| 欧美日韩一区二区在线视频| 一区二区理论电影在线观看| 在线视频中文字幕一区二区| 亚洲一区二三区| 在线亚洲免费视频| 亚洲精品一二三| 欧美日韩亚洲综合一区二区三区| 亚洲成人免费电影| 日韩一二三区视频| 极品销魂美女一区二区三区| 亚洲精品一区二区三区福利| 国产剧情一区在线| 国产精品夫妻自拍| 亚洲一区中文在线| 色视频一区二区| 欧美日韩大陆在线| 久久久高清一区二区三区| 亚洲男女一区二区三区| 成人在线综合网站| 久久久www免费人成精品| 久久国产人妖系列| 日韩一区二区三区视频| 亚洲成人av一区| 欧美日韩精品三区| 国产一区二区不卡在线| 精品在线观看视频| 国产精品动漫网站| 日本不卡一二三| 欧美岛国在线观看| 91老司机福利 在线| 色综合天天天天做夜夜夜夜做| 欧美另类一区二区三区| 久久99精品久久久久久久久久久久| 国产日韩av一区| 欧美在线制服丝袜| 国产不卡视频在线播放| 亚洲成人免费影院| 国产精品丝袜91| 制服丝袜在线91| 99re热视频这里只精品| 麻豆国产欧美日韩综合精品二区| 中文字幕永久在线不卡| 欧美成人女星排名| 欧美人动与zoxxxx乱| www.日韩在线| 一区二区三区精品在线| 2022国产精品视频| 欧美日韩不卡一区二区| 一本色道久久加勒比精品| 国产一区二区三区视频在线播放| 亚洲高清不卡在线观看| 自拍偷拍国产精品| 国产日韩精品一区二区浪潮av| 欧美麻豆精品久久久久久| 色综合天天综合| bt欧美亚洲午夜电影天堂| 久久电影网站中文字幕| 日本aⅴ亚洲精品中文乱码| 亚洲一区二区黄色| 中文字幕亚洲综合久久菠萝蜜| 久久久久亚洲综合| xvideos.蜜桃一区二区| 日韩欧美国产1| 欧美一级在线观看| 4438x亚洲最大成人网| 欧美午夜精品理论片a级按摩| 91影院在线观看| 99久久久精品免费观看国产蜜| 国产精品1区2区3区在线观看| 久久精品99久久久| 另类调教123区| 理论电影国产精品| 国产精品亚洲第一区在线暖暖韩国| 日本sm残虐另类| 久久99久久久欧美国产| 美国精品在线观看| 国产毛片精品一区| 国产精品综合二区| 国产成人在线免费| kk眼镜猥琐国模调教系列一区二区| 国产精品12区| av一区二区久久| 一本色道久久综合亚洲91| 欧美无乱码久久久免费午夜一区| 在线观看视频一区二区 | 午夜a成v人精品| 日韩中文字幕av电影| 日本成人在线不卡视频| 紧缚奴在线一区二区三区| 国产精品自在欧美一区| 不卡的电影网站| 欧美主播一区二区三区| 欧美一区二区在线视频| 国产精品美女久久久久久久| 久久精品亚洲精品国产欧美 | 一区二区三区高清| 一区二区免费在线| 日韩精品电影一区亚洲| 久久精品国产99久久6| 国产成人久久精品77777最新版本| 国产不卡一区视频| 免费人成精品欧美精品| 日韩亚洲欧美中文三级| 免费久久精品视频| 欧美性一级生活| 国产日韩高清在线| 秋霞影院一区二区| 欧美性猛片aaaaaaa做受| 91精品国产手机| 亚洲午夜视频在线观看| 日韩成人av影视| eeuss国产一区二区三区| 日韩免费高清视频| 国产精品综合av一区二区国产馆| 99在线精品视频| 久久久国产午夜精品| 男人操女人的视频在线观看欧美| 欧美日韩的一区二区| 精品一区二区三区欧美| 日韩亚洲欧美综合| 不卡一区二区在线| 午夜精品福利在线| 国产网站一区二区| 欧洲国内综合视频|