如何避免页面锁定导致死锁,并发更新到不同的行?

时间:2019-07-30 15:10:26

标签: sql sql-server database-deadlocks

CREATE TABLE MY_DATA (
    FIRST_KEY VARCHAR(255) NOT NULL,
    SECOND_KEY VARCHAR(255) NULL,
    AUTO_VALUE INT IDENTITY NOT NULL,
    DATA_FIELD_1 VARCHAR(255) NULL,
    DATA_FIELD_2 VARCHAR(255) NULL,
    DATA_FIELD_3 VARCHAR(255) NULL,
    DATA_FIELD_4 VARCHAR(255) NULL,
    DATA_FIELD_5 VARCHAR(255) NULL,
    DATA_FIELD_6 VARCHAR(255) NULL,
    DATA_FIELD_7 VARCHAR(255) NULL,
    DATA_FIELD_8 VARCHAR(255) NULL,
    DATA_FIELD_9 VARCHAR(255) NULL
);

ALTER TABLE MY_DATA ADD CONSTRAINT PK_MY_DATA FIRST_KEY PRIMARY KEY CLUSTERED (FIRST_KEY);
CREATE NONCLUSTERED INDEX IDX_MY_DATA_SECOND_KEY ON TABLE MY_DATA (SECOND_KEY);

-SECOND_KEY是一个外键,它根据数据字段进行如下更改(WHERE子句的数据字段部分每次更改哪个字段和值)。这是发生死锁的时候。

-使用AUTO_VALUE将更新分为多个块(并且每组更新都并行进行)。

第一个过程

UPDATE SET SECOND_KEY=NULL WHERE SECOND_KEY="old value" AND AUTO_VALUE IS BETWEEN 1 AND 250000;
UPDATE SET SECOND_KEY="new value" WHERE SECOND_KEY IS NULL AND AUTO_VALUE IS BETWEEN 1 AND 250000 AND DATA_FIELD_3='d3 value' AND DATA_FIELD_5 != 'unwanted value';

第二过程

UPDATE SET SECOND_KEY=NULL WHERE SECOND_KEY="old value" AND AUTO_VALUE IS BETWEEN 250001 AND 500000;
UPDATE SET SECOND_KEY="new value" WHERE SECOND_KEY IS NULL AND AUTO_VALUE IS BETWEEN 250001 AND 500000 AND DATA_FIELD_3='d3 value' AND DATA_FIELD_5 != 'unwanted value';

僵局情况

我看到一个死锁,第一个进程具有“ U”页面锁定,而第二个进程希望在同一页面上具有“ IX”页面锁定。对于其他页面,第二个进程具有“ IX”页面锁定,而第一个进程希望对该页面具有“ U”页面锁定。

其他表用途

更改SECOND_KEY时不会执行这些查询。

-通过查找主键完成表DATA_FIELD的更改

-其他查询通过第二个键查找数据

0 个答案:

没有答案