この記事では主に SQL Server の 7 つのソリューションについて説明します 同時実行処理 興味のある方は参照してください
このセクションでは、次のように説明します。同時実行で最も一般的な状況は、行レコードが存在しない場合に更新することですが、これがうまく処理されない場合、重複キーを挿入するのは非常に簡単です。行レコードが同時に存在する場合に更新する方法を 7 つ紹介し、最適な解決策を包括的に分析してみましょう。
存在したらすぐに更新するための 7 つのオプションについて説明します
まず、テスト テーブルを作成します
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解決策 1
(トランザクションを有効にする) 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
この場合はさらに悪化し、デッドロックに直結します
今回は、分離レベルを最高の分離レベルに上げることで問題は解決します。重複キーの挿入の問題は解決されますが、更新ではコミットせずに排他ロックを取得し、この時点で別のプロセスが共有ロックを取得するために クエリ
(分離レベルを上げる + 適切なロック)この時点では、次のように、最も高い分離レベルの追加に基づいて更新ロックを追加します。データのクエリ時に共有ロックの代わりに更新ロックを使用すると、第 1 に、他のトランザクションをブロックすることなくデータを読み取ることができます。第 2 に、データが最後に変更されてから変更されていないことも保証されます。このようにしてデッドロックの問題を解決します。この解決策は実行可能であるように見えますが、同時実行性が高い場合に実行可能かどうかはわかりません。
解決策 5
(行バージョン管理スナップショットの分離レベルを上げる)
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
上記の解決策は、重複キーの挿入の問題も引き起こすため、お勧めできません。
(分離レベル + テーブル変数を増やす)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
多くの認証を経て、テーブル変数の形式で実装することが可能であると思われます。
(分離レベルを上げる + マージ)
存在を達成するか更新するには 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)) 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複数の認証の後、100 スレッドでも 200 スレッドでも、異常な情報はありません。
概要 このセクションでは、存在する場合は更新、そうでない場合は同時挿入の問題の解決策を詳細に説明しました。現在、上記の 3 つの解決策が実行可能です。
解決策 1
(最高の分離レベル + 更新ロック)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今のところ、私はこの 3 つの解決策しか思いつきません。個人的には解決策 1 と 3 をお勧めします。うまくいったらコメントを残してください。後で追加します。
解決策 2
(最高の分離レベル + テーブル変数)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
暂时只能想到这三种解决方案,个人比较推荐方案一和方案三, 请问您有何高见,请留下您的评论若可行,我将进行后续补充。
以上がSQL Server の同時処理が存在する場合の更新ソリューションに関するディスカッション_MsSqlの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

win7补丁包(UpdatePack7)是俄罗斯大神制作的一款Win7系统补丁自动安装精灵,它支持Win764位和32位,集成了Win7发布至今所有补丁,还包含了NVME协议补丁,USB3.0补丁等等。win7补丁包(UpdatePack7)【64位+32位】下载UpdatePack7参数介绍/NVMe(集成NVMe驱动)/S(静默安装,不更改IE版本,不重启)/Silent(自动安装,界面显示安装进度)/Temp(指定释放路径到临时文件夹)/IE11(更新安装InternetExplorer1

WindowsServerBackup是WindowsServer操作系统自带的一个功能,旨在帮助用户保护重要数据和系统配置,并为中小型和企业级企业提供完整的备份和恢复解决方案。只有运行Server2022及更高版本的用户才能使用这一功能。在本文中,我们将介绍如何安装、卸载或重置WindowsServerBackup。如何重置Windows服务器备份如果您的服务器备份遇到问题,备份所需时间过长,或无法访问已存储的文件,那么您可以考虑重新设置WindowsServer备份设置。要重置Windows

win10电脑老是提醒更新重启怎么办?win10的更新问题一直是大家比较头疼的,无论是更新前还是更新后,系统老是提醒更新重启,十分烦人。其实我们只要将对应服务关闭就可以了,下面就一起来看看具体方法吧。win10电脑老是提醒更新重启解决办法一、更新前提示1、首先我们在开始菜单中打开设置。2、选择更新和安全。3、再点击高级选项。4、将更新通知关闭即可。二、更新后提醒1、其实我们在完成更新之后,系统也有可能会老是提醒我们重启。2、这时候我们需要先右键计算机,选择理3、在系统工具中找到图所示。4、然后我

Vue是一个流行的JavaScript框架,它通过使用组件化开发模式,使得我们可以轻松地构建可重用的交互式用户界面。但是某些情况下,我们需要手动更新组件而不是等待数据驱动更新,这时候可以使用Vue提供的$forceUpdate方法。在这篇文章中,我们将详细讨论Vue中如何使用$forceUpdate方法强制更新组件。Vue组件的渲染是由Vue的响应式系统驱动

CakePHP是一个流行的PHP框架,它提供了方便的ORM(对象关系映射)功能,使得查询和更新数据库变得非常容易。本文将介绍如何在CakePHP中进行数据查询和更新。我们将从简单的查询和更新开始,逐步深入,了解如何使用条件和关联的模型来更复杂地查询和更新数据。基本查询首先,让我们看看如何进行最简单的查询。假设我们有一个名为“Users”的数据表,并且我们想要

Win11bios怎么更新?更新BIOS可以支持最新的硬件,也可以对以往的一些硬件进行优化。近期有部分Win11用户想要更新BIOS,但是不太清楚应该如何操作,对于这一情况,下面小编为大家带来了详细的Win11更新bios的方法,我们一起来看看吧。 Win11更新bios的方法 在进行更新之前,您需要执行一些任务。首先,您需要检查您的BIOS版本并记下它。然后,您可以继续为您的特定系统下载正确的BIOS。 1、检查您的BIOS版本 同时按下Windows和R键。 键入msinfo3

在发布WindowsServer的build26040版本之际,微软公布了该产品的官方名称:WindowsServer2025。一同推出的,还有Windows11WindowsInsiderCanaryChannel版本的build26040。有些朋友可能还记得,多年前有人成功将WindowsNT从工作站模式转换为服务器模式,显示微软操作系统各版本之间的共性。尽管现在微软的服务器操作系统版本和Windows11之间有明显区别,但关注细节的人可能会好奇:为什么WindowsServer更新了品牌,

微软6月24号正式公布了win11系统,可以看到用户界面、开始菜单等和Windows10X中发现的非常相似。有的朋友在使用预览版的时候发现用的不习惯,想要改win10系统开使用,那么我们要如何操作呢,下面我们就来看看win11改win10系统教程,一起来学习一下吧。1、第一步是从Windows11打开新设置。在这里,您需要转到图像中显示的系统设置。2、在系统设置下,选择“恢复”选项。在这里,您将能够看到“以前版本的窗口”选项。您还可以在它旁边看到一个“返回”按钮,单击此按钮。3、您可以指定要返回


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

DVWA
Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

Dreamweaver Mac版
ビジュアル Web 開発ツール
