【发布时间】:2019-11-07 13:14:06
【问题描述】:
我有一项服务可以插入和更新表中的行。
当有人同时对服务发起 20 次调用时,问题就开始了,导致一些事务回滚并出现死锁错误。
"Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction."
问题是我的查询在逻辑上无法遇到死锁。
我的服务有 4 个不同的查询,但我们可以忽略其中的 2 个,因为它们是单行插入,它们不需要锁定任何行。
其他 2 个查询是这样的:
UPDATE Documents SET read = 1 WHERE id = ?
和
UPDATE Documents SET name = ?, title = ? WHERE id = ?
没有两行具有相同的 id,所以我不明白如何可能发生跨块。
我正在使用语句:
try {
PreparedStatement st = con.prepareStatement(updateQuery);
st.setString(1, true);
int rowsUpdated = st.executeUpdate();
if(rowsUpdated == 0) {
st = con.prepareStatement(insertQuery);
st.setString(1, "example");
[...]
st.executeUpdate();
}
我正在使用 SQL Server 2016,sqljdbc4 库。我可以提供任何可以提供帮助的进一步信息。
【问题讨论】:
-
死锁的 xml 报告会很有帮助。它可以取自
system_health扩展事件会话。 -
还提供 DDL,包括表的索引。死锁可能发生在非聚集索引上,以及受级联外键影响的相关表上。
标签: java sql-server jdbc deadlock