【问题标题】:Deadlock with a very simple query一个非常简单的查询死锁
【发布时间】: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


【解决方案1】:

解决方案是索引where 子句中的列。

查询似乎阻塞了所有行,而 SCANNING 而不是 SEEKING 特定行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多