我遇到了一个奇怪的问题,我不确定如何正确解决它。我有一个表被击中很多,并开始产生死锁。
我的表格如下:
CREATE TABLE object
(
id NVARCHAR(255) NOT NULL,
type NVARCHAR(255) NOT NULL,
subId NVARCHAR(255) NOT NULL,
scheduleTime BIGINT NOT NULL,
message NVARCHAR(MAX),
status TINYINT,
send_to NVARCHAR(255),
owner NVARCHAR(255),
date DATETIME,
retry TINYINT,
CONSTRAINT pk PRIMARY KEY(id, type, subId, scheduleTime, send_to)
);
冲突的两个查询是声明查询和一个发布查询的一个更新。
所以我的工作人员这样做:
查询A:
UPDATE TOP (?) object
SET owner = ?, status = 2
WHERE owner IS NULL
AND send_date <= ?
AND status = 1
查询B:
UPDATE object
SET status = %s,
owner = NULL,
retry = retry + 1
WHERE ( (%s) AND owner='%s');
简而言之,查询A:
查询B:
我的问题:
这2个查询如何死锁?它们在设计上是否可以同时在同一行上运行?他们不应该互相僵持。
更多信息:
从我的死锁图中,我可以看到SQLServer正在取出一个PageLock。 从现有的死锁中我可以看出,查询被杀死并回滚是随机的。
我正在使用SQL Server 2012和Microsoft 4.2 JDBC驱动程序
我的问题:
1.1。更改查询A以预先进行选择,然后使用主键来更新它们。 1.2。更改查询以专门取出Rowlock。
将锁更改为行锁是否有问题?我会遇到任何风险/性能问题?
在应用程序层添加重试逻辑。 我可以捕获异常并重试直到它通过。不理想,因为它有点杀戮性能。
将隔离级别更改为READ_UNCOMMITTED 由于我的设计查询永远无法处理相同的数据,因此将隔离级别设置为不可以吗?
对此的任何帮助都会很棒。我仍然在努力了解这是如何以及为什么会发生这种情况,这使得很难为它制定计划。
谢谢,
阿图尔