SQL Azure:并发删除操作的死锁

时间:2013-03-25 19:19:57

标签: tsql azure azure-sql-database

由于并发删除操作导致我的SQL azure数据库遇到一些死锁,我不确定如何解决它。我已将情况简化到最基本的水平。我有下表:

CREATE TABLE [dbo].[Test2013](
    [ClientID] [int] NOT NULL,
    [ID] [uniqueidentifier] NOT NULL,
    [Value] [int] NOT NULL,
 CONSTRAINT [dbo-Test2013] PRIMARY KEY CLUSTERED 
(
    [ClientID] ASC,
    [ID] ASC
)
 WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
       IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
       ALLOW_PAGE_LOCKS  = ON)
)

GO

ALTER TABLE [dbo].[Test2013] ADD CONSTRAINT [Test2013-ID-Default-Value]
     DEFAULT (newid()) FOR [ID]
GO

导致问题的查询如下:

INSERT INTO [Test2013]
    ([ClientID],[ID],[Value])
    SELECT
        CAST(-2147483648 AS INT) [ClientID], 
        '82ecb924-d2f0-44ee-9a8e-5240d12de088' [ID], 
        CAST(1 AS INT) [Value]

INSERT INTO [Test2013]
    ([ClientID],[ID],[Value])
    SELECT
        CAST(-2147483648 AS INT) [ClientID], 
        '82ecb924-d2f0-44ee-9a8e-5240d12de077' [ID], 
        CAST(2 AS INT) [Value]

 DECLARE @MyDateTime DATETIME
SET @MyDateTime = DATEADD(s,5,GETDATE())

DECLARE @MyDateTime2 DATETIME
SET @MyDateTime2 = DATEADD(ms,1,@MyDateTime)

BEGIN tran
    WAITFOR TIME @MyDateTime;
    DELETE FROM [Test2013]
    WHERE [ID] = '82ecb924-d2f0-44ee-9a8e-5240d12de088';
Commit tran

BEGIN tran
    WAITFOR TIME @MyDateTime2;
    DELETE FROM [Test2013]
    WHERE [ID] = '82ecb924-d2f0-44ee-9a8e-5240d12de077';
Commit tran

我认为这将是相对微不足道的,但我无法找出实际锁定查询的内容。我检查了sys.events_log表,它不包含任何新的死锁事件。我以前见过其他死锁,但他们都抛出了我可以处理的异常,这个只是无限期挂起。

另一方面,如果我将第二次操作延迟50 ms,则可以正常工作。

1 个答案:

答案 0 :(得分:0)

悬挂在这里并不是真的由死锁引起的,而是因为你正在等待已经过去的时间。以下是您的查询的修改版本,它会将当前时间与来自我的运行的消息一起保留。正如您所看到的,当您等待@ MyDateTime2时,它已经过去了。 50 ms工作的原因是因为完成所有工作不需要50 ms。我将WAITFOR TIME更改为WAITFOR DELAY,它可以正常工作。但它并没有真正等待一毫秒。

INSERT INTO [Test2013]
    ([ClientID],[ID],[Value])
    SELECT
        CAST(-2147483648 AS INT) [ClientID], 
        '82ecb924-d2f0-44ee-9a8e-5240d12de088' [ID], 
        CAST(1 AS INT) [Value]

INSERT INTO [Test2013]
    ([ClientID],[ID],[Value])
    SELECT
        CAST(-2147483648 AS INT) [ClientID], 
        '82ecb924-d2f0-44ee-9a8e-5240d12de077' [ID], 
        CAST(2 AS INT) [Value]

 DECLARE @MyDateTime DATETIME
SET @MyDateTime = DATEADD(s,5,GETDATE())

PRINT(CONVERT(varchar, @MyDateTime, 121))
DECLARE @MyDateTime2 DATETIME
SET @MyDateTime2 = DATEADD(ms,1,@MyDateTime)

PRINT(CONVERT(varchar, @MyDateTime2, 121))
BEGIN tran
PRINT(CONVERT(varchar, getdate(), 121))
    WAITFOR TIME @MyDateTime;
PRINT(CONVERT(varchar, getdate(), 121))
    DELETE FROM [Test2013] 
    WHERE [ID] = '82ecb924-d2f0-44ee-9a8e-5240d12de088';
PRINT(CONVERT(varchar, getdate(), 121))
Commit tran

BEGIN tran
PRINT(CONVERT(varchar, getdate(), 121))
    WAITFOR TIME @MyDateTime2;
PRINT(CONVERT(varchar, getdate(), 121))
    DELETE FROM [Test2013]
    WHERE [ID] = '82ecb924-d2f0-44ee-9a8e-5240d12de077';
PRINT(CONVERT(varchar, getdate(), 121))
Commit tran

取消查询时产生的消息:

(1 row(s) affected)

(1 row(s) affected)
2013-06-21 15:13:09.980
2013-06-21 15:13:09.980
2013-06-21 15:13:04.980
2013-06-21 15:13:09.997

(1 row(s) affected)
2013-06-21 15:13:09.997
2013-06-21 15:13:10.017
Query was cancelled by user.

改为使用WAITFOR DELAY:INSERT INTO [Test2013]         ([客户端ID],[ID],[值])         选择             CAST(-2147483648 AS INT)[ClientID],             '82ecb924-d2f0-44ee-9a8e-5240d12de088'[ID],             CAST(1 AS INT)[值]

INSERT INTO [Test2013]
    ([ClientID],[ID],[Value])
    SELECT
        CAST(-2147483648 AS INT) [ClientID], 
        '82ecb924-d2f0-44ee-9a8e-5240d12de077' [ID], 
        CAST(2 AS INT) [Value]


BEGIN tran
PRINT(CONVERT(varchar, getdate(), 121))
    WAITFOR delay '00:00:05'
PRINT(CONVERT(varchar, getdate(), 121))
    DELETE FROM [Test2013] 
    WHERE [ID] = '82ecb924-d2f0-44ee-9a8e-5240d12de088';
PRINT(CONVERT(varchar, getdate(), 121))
Commit tran

BEGIN tran
PRINT(CONVERT(varchar, getdate(), 121))
    WAITFOR delay '00:00:00.001'
PRINT(CONVERT(varchar, getdate(), 121))
    DELETE FROM [Test2013]
    WHERE [ID] = '82ecb924-d2f0-44ee-9a8e-5240d12de077';
PRINT(CONVERT(varchar, getdate(), 121))
Commit tran