婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 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并發處理存在就更新解決方案探討的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    日日摸夜夜添夜夜添亚洲女人| 成人国产精品免费| 日产国产高清一区二区三区| 国产suv精品一区二区三区| 日韩一区二区精品在线观看| 欧美视频在线一区二区三区| 国内成+人亚洲+欧美+综合在线| 色999日韩国产欧美一区二区| 国产精品久久毛片av大全日韩| 国产永久精品大片wwwapp| 欧洲另类一二三四区| 国产精品福利一区二区| 亚洲狠狠丁香婷婷综合久久久| 热久久一区二区| 国产成人免费视频网站高清观看视频| 91精品国产色综合久久不卡电影| 亚洲精品ww久久久久久p站 | 亚洲一区二区欧美| 91精品国产欧美一区二区| 久久成人18免费观看| 国产欧美日韩麻豆91| 在线影视一区二区三区| 久久国产精品第一页| 亚洲三级电影全部在线观看高清| 欧美亚洲动漫另类| 美女精品一区二区| 国产欧美精品一区aⅴ影院 | 欧美一级免费观看| 国产激情视频一区二区在线观看| 国产精品美女久久久久久久久久久| 99精品国产一区二区三区不卡| 亚洲午夜精品一区二区三区他趣| 日韩精品中文字幕在线不卡尤物| av在线不卡网| 日韩va欧美va亚洲va久久| 久久综合中文字幕| 欧美色图在线观看| 成人app下载| 激情图片小说一区| 亚洲福利国产精品| 1024成人网| 国产午夜精品在线观看| 成人福利电影精品一区二区在线观看| 亚洲日本护士毛茸茸| 日韩一区二区三区四区| 99re66热这里只有精品3直播| 日本欧美久久久久免费播放网| 国产精品污污网站在线观看 | 色综合久久中文综合久久牛| 天堂成人免费av电影一区| 国产精品私人自拍| 制服丝袜在线91| 色婷婷综合久久久久中文| 国产福利91精品一区二区三区| 亚洲成av人在线观看| 国产精品久久久久久户外露出 | 欧美色电影在线| 国产传媒久久文化传媒| 美国三级日本三级久久99| 中文字幕日韩一区| 精品第一国产综合精品aⅴ| 欧美一区二区视频网站| 91视频免费观看| 99re成人在线| 91小视频免费看| 91在线无精精品入口| 99综合电影在线视频| 国产美女娇喘av呻吟久久| 狠狠色丁香久久婷婷综合_中| 蜜臀久久99精品久久久久宅男 | 99在线精品一区二区三区| 成人国产亚洲欧美成人综合网| 久久不见久久见免费视频1| 美脚の诱脚舐め脚责91| 视频一区中文字幕国产| 日本视频一区二区| 国模娜娜一区二区三区| 国产精品自在欧美一区| 成人午夜看片网址| 91亚洲大成网污www| 成人的网站免费观看| 91同城在线观看| 欧美优质美女网站| 欧美日韩精品免费观看视频| 欧美精品乱码久久久久久按摩 | 7777精品伊人久久久大香线蕉完整版 | 国产一区久久久| 成人国产免费视频| 欧美综合一区二区三区| 制服丝袜国产精品| 久久伊99综合婷婷久久伊| 国产精品欧美精品| 亚洲综合图片区| 精品系列免费在线观看| 成人黄色软件下载| 欧美日韩你懂得| 国产女主播在线一区二区| 亚洲美女区一区| 精一区二区三区| 91美女福利视频| 欧美高清视频一二三区| 久久久久久9999| 一区2区3区在线看| 欧美日韩国产小视频| 亚洲一区在线电影| 亚洲丶国产丶欧美一区二区三区| 国产精品一级片| 99精品国产一区二区三区不卡| 欧美日本一道本| 制服丝袜在线91| 亚洲欧美一区二区三区极速播放| 日本aⅴ精品一区二区三区 | **性色生活片久久毛片| 日韩电影在线一区二区| 成人午夜精品一区二区三区| 7777精品久久久大香线蕉| 欧美大度的电影原声| 亚洲欧美经典视频| 丰满亚洲少妇av| 91精品午夜视频| 日本久久精品电影| 亚洲婷婷综合色高清在线| 日韩欧美综合一区| 国产1区2区3区精品美女| 亚洲精品第1页| 成人性生交大片免费| 日韩小视频在线观看专区| 亚洲日本青草视频在线怡红院| 丝袜脚交一区二区| 在线看国产一区| 亚洲欧美一区二区久久| 成人黄色av电影| 中文字幕成人av| 国产一区二区精品久久99| 日韩精品一区二区三区中文不卡| 一区二区国产盗摄色噜噜| 99re亚洲国产精品| 久久综合资源网| 国产人久久人人人人爽| 一区二区三区四区在线免费观看| 国产精品77777| 久久亚洲二区三区| 久久国产麻豆精品| 欧美一级日韩免费不卡| 一区在线中文字幕| 91网站黄www| 午夜影视日本亚洲欧洲精品| 欧美日本韩国一区| 久久精品久久久精品美女| 日韩欧美一区在线| 久草中文综合在线| 国产日韩v精品一区二区| 国产91丝袜在线18| 日韩一区二区免费视频| 日本中文字幕一区| 亚洲精品一区在线观看| 国产成人99久久亚洲综合精品| 国产精品日日摸夜夜摸av| 日本道在线观看一区二区| 精品国产免费视频| 日韩理论在线观看| 日本91福利区| 亚洲主播在线播放| 欧美aaaaa成人免费观看视频| 7777精品伊人久久久大香线蕉经典版下载 | 国产精品91一区二区| 欧美经典一区二区| 91免费视频观看| 亚洲一区二区三区四区不卡| 欧美一区二区黄| 成人免费观看男女羞羞视频| 亚洲曰韩产成在线| 欧美哺乳videos| 91网站最新地址| 精品无人码麻豆乱码1区2区 | 精品国产一区二区三区久久影院| 精品奇米国产一区二区三区| 成人av影院在线| 黄网站免费久久| 亚洲人成精品久久久久久| 91行情网站电视在线观看高清版| 日产国产高清一区二区三区| 欧美国产精品v| 欧美一区二区高清| 99re在线视频这里只有精品| 免费精品视频在线| 亚洲乱码日产精品bd| 国产亚洲欧美激情| 91精品国产入口在线| 成人污污视频在线观看| 日本欧美大码aⅴ在线播放| 中文字幕欧美一| 欧美国产精品专区| 精品剧情v国产在线观看在线| 欧美中文字幕一区二区三区| 夜夜嗨av一区二区三区四季av| 美洲天堂一区二卡三卡四卡视频 | 国产成人高清在线| 欧美色图激情小说| 亚洲精品免费看|