Ari*_*ian 3 sql sql-server sql-server-2005 sql-server-2008
考虑这个简单的表:

表的创建语句是:
CREATE TABLE [dbo].[Test_Serializable](
[Id] [int] NOT NULL,
[Name] [nvarchar](50) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
因此没有任何主键或索引。
考虑到它是空的,没有任何行。(1,'nima')我想插入此行,但我想检查是否有一个行,如果Id=1是RAISERROR,则调用,如果没有,则要插入行。我编写此脚本:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRY
BEGIN TRAN ins
IF EXISTS(SELECT * FROM Test_Serializable ts WITH(xlock,ROWLOCK) WHERE ts.Id=1)
RAISERROR(N'Row Exists',16,1);
INSERT INTO Test_Serializable
(
Id,
[Name]
)
VALUES
(
1,
'nima'
)
COMMIT TRAN ins
END TRY
BEGIN CATCH
DECLARE @a NVARCHAR(1000);
SET @a=ERROR_MESSAGE();
ROLLBACK TRAN ins
RAISERROR(@a,16,1);
END CATCH
Run Code Online (Sandbox Code Playgroud)
该脚本可以正常工作,但有一点很有趣。
我从2个SSMS运行此脚本,然后逐步运行这2个脚本(在调试模式下)。有趣的是,我的表没有行,而到达IF EXIST语句锁定表时是其中一个脚本。
我的问题是是否(XLOCK,ROWLOCK)因为没有行而锁定整个表?还是锁定了幻像行:) !! ???
编辑1)
这是我的情况:
我有一个表,例如6个字段

这是唯一性规则:
1)City_Code + F1_Code是唯一的
2)City_Code + F2_Code是唯一的
3)城市代码+ F3代码+ F4代码是uinque
问题是用户可能想填充city_code,F1_Code并且在需要将其插入其他文件时,我们必须具有Empty String或0(对于数字字段)值。
如果用户要填写City_Code + F3_Code + F4_Code,则F1_Code和F2_Code必须具有Empty String值
如何更好地检查此规则?我无法为每个规则创建任何唯一索引
为了回答您的问题,SERIALIZABLE隔离级别执行范围锁定,该范围锁定将包括范围内不存在的行。
http://msdn.microsoft.com/en-us/library/ms191272.aspx
键范围锁定可确保以下操作可序列化:
范围扫描查询
单行获取不存在的行
删除操作
插入操作
| 归档时间: |
|
| 查看次数: |
3472 次 |
| 最近记录: |