除了(XLOCK,ROWLOCK)没有行了吗?

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=1RAISERROR,则调用,如果没有,则要插入行。我编写此脚本:

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_codeF1_Code并且在需要将其插入其他文件时,我们必须具有Empty String0(对于数字字段)值。

如果用户要填写City_Code + F3_Code + F4_Code,则F1_Code和F2_Code必须具有Empty String

如何更好地检查此规则?我无法为每个规则创建任何唯一索引

Cod*_*ian 5

为了回答您的问题,SERIALIZABLE隔离级别执行范围锁定,该范围锁定将包括范围内不存在的行。

http://msdn.microsoft.com/en-us/library/ms191272.aspx

键范围锁定可确保以下操作可序列化:

范围扫描查询

单行获取不存在的行

删除操作

插入操作