Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如果不存在事务,我应该为以下插入使用哪个隔离级别?_.net_Sql_Linq To Sql_Transactions_Isolation Level - Fatal编程技术网

.net 如果不存在事务,我应该为以下插入使用哪个隔离级别?

.net 如果不存在事务,我应该为以下插入使用哪个隔离级别?,.net,sql,linq-to-sql,transactions,isolation-level,.net,Sql,Linq To Sql,Transactions,Isolation Level,我已经编写了一个LINQtoSQL程序,它基本上执行ETL任务,我注意到许多地方并行化将提高其性能。但是,我关心的是,当两个线程执行以下任务(psuedo代码)时,如何防止违反唯一性约束 通常,此代码执行SELECT语句以测试记录是否存在,如果记录不存在,则执行INSERT语句。它由隐式事务封装 当两个线程为同一个recordText实例运行此代码时,我希望防止它们同时确定该记录不存在,从而尝试创建相同的记录。隔离级别和显式事务将很好地工作,但我不确定应该使用哪个隔离级别--Serializab

我已经编写了一个LINQtoSQL程序,它基本上执行ETL任务,我注意到许多地方并行化将提高其性能。但是,我关心的是,当两个线程执行以下任务(psuedo代码)时,如何防止违反唯一性约束

通常,此代码执行
SELECT
语句以测试记录是否存在,如果记录不存在,则执行
INSERT
语句。它由隐式事务封装


当两个线程为同一个
recordText
实例运行此代码时,我希望防止它们同时确定该记录不存在,从而尝试创建相同的记录。隔离级别和显式事务将很好地工作,但我不确定应该使用哪个隔离级别--
Serializable
,但似乎太严格了。有更好的选择吗?

我使用类似于下面所示的SQL来避免这种情况
UPDLOCK
指定在事务完成之前获取并保持更新锁,
HOLDLOCK
相当于
SERIALIZABLE
SERIALIZABLE
通过将共享锁保持到事务完成,而不是在不再需要所需的表或数据页时(无论事务是否已完成)释放共享锁,从而使共享锁更具限制性。扫描的语义与在
SERIALIZABLE
隔离级别运行的事务相同
HOLDLOCK
仅适用于为其指定的表或视图,并且仅适用于由使用它的语句定义的事务的持续时间
HOLDLOCK
不能用于包含
FOR BROWSE
选项的
SELECT
语句中

declare @LocationID          int
declare @LocationName        nvarchar (50)

/* fill in LocationID and LocationName appropriately */

INSERT dbo.Location
(LocationID, LocationName)
SELECT @LocationID, @LocationName
WHERE NOT EXISTS (
   SELECT L.*
   FROM dbo.Location L WITH (UPDLOCK, HOLDLOCK)
   WHERE L.LocationID = @LocationID)

根据对的回答,Serializable似乎是一种可行的方法。

我使用类似于下面所示的SQL来避免这种情况
UPDLOCK
指定在事务完成之前获取并保持更新锁,
HOLDLOCK
相当于
SERIALIZABLE
SERIALIZABLE
通过将共享锁保持到事务完成,而不是在不再需要所需的表或数据页时(无论事务是否已完成)释放共享锁,从而使共享锁更具限制性。扫描的语义与在
SERIALIZABLE
隔离级别运行的事务相同
HOLDLOCK
仅适用于为其指定的表或视图,并且仅适用于由使用它的语句定义的事务的持续时间
HOLDLOCK
不能用于包含
FOR BROWSE
选项的
SELECT
语句中

declare @LocationID          int
declare @LocationName        nvarchar (50)

/* fill in LocationID and LocationName appropriately */

INSERT dbo.Location
(LocationID, LocationName)
SELECT @LocationID, @LocationName
WHERE NOT EXISTS (
   SELECT L.*
   FROM dbo.Location L WITH (UPDLOCK, HOLDLOCK)
   WHERE L.LocationID = @LocationID)
根据对的回答,序列化似乎是一条出路