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