同时执行UPDATE时出现死锁

Posted

技术标签:

【中文标题】同时执行UPDATE时出现死锁【英文标题】:Getting deadlock when execute UPDATE at same time 【发布时间】:2012-04-27 21:56:58 【问题描述】:

我正在对应用程序进行负载测试并遇到死锁错误。该场景是由 10 个不同的用户同时插入和更新数据库。我上网查了,还是没找到解决的办法。这里附上我涉及死锁的示例代码。

谁能给我一些解决死锁的建议?提前谢谢你。

SampleController:

onSubmit(userAccount)

     sampleBO.testDeadLock(userAccount.getUserAccountId());


样品BO:

public void testInsert(Long id)

    sampleDAO.testInsert4(id);      


public void testDeadLock(Long id)

    testInsert(id);
    sampleDAO.testUpdate4(id);  

SampleDAO:

public void testInsert4(Long id)

    StringBuffer sbSql = new StringBuffer();
    sbSql.append(" INSERT INTO Test ");
    sbSql.append(" ( ");
    sbSql.append(" id, ");
    sbSql.append(" note ");
    sbSql.append(" ) ");
    sbSql.append(" VALUES ");
    sbSql.append(" (");
    sbSql.append(""+id+",");
    sbSql.append(" 'test' ");
    sbSql.append(" )");

    //Execute SQL using Spring's JDBC Templates
    this.getSimpleJdbcTemplate().update(sbSql.toString());


public void testUpdate4(Long id)
       
    StringBuffer sbSql = new StringBuffer();
    sbSql.append(" UPDATE Test WITH(ROWLOCK) SET ");
    sbSql.append(" note = 'test1111'");
    sbSql.append(" WHERE id="+id);

    //Execute SQL using Spring's JDBC Templates
    this.getSimpleJdbcTemplate().update(sbSql.toString());

【问题讨论】:

SQL 的品牌和版本是什么? 另外,请发布表定义,包括任何键、索引、约束和/或触发器,因为问题所在的可能性为 90%。 我错过了什么吗?看起来您正在同步调用两个执行,因此 testUpdate4 调用不应在插入完成之前触发。 您好,我不确定您是否遇到了死锁,您的代码不够复杂,无法导致死锁。您能否描述一下您认为自己陷入死锁的原因、收到的错误以及最重要的是您使用的 SQL 风格? 【参考方案1】:

如果发生死锁,则不是来自您提供的代码,除非:

您有多个同时运行的测试程序实例。 上述代码是异步运行的 - 但情况似乎并非如此。 当您运行这些测试时,数据库上还有其他活动。

我的钱在最后一个。

您可以通过执行 SQL 跟踪并准确识别正在运行的内容和时间来找出这些死锁发生的原因。


每个都有自己的,但是您知道您可以像这样声明您的 sql 查询吗? @ 允许文本进入多行,也可以转义反斜杠等特殊字符。

string sbSql = @"
    INSERT INTO Test (id, note)
    VALUES (0, 'test')";

sbSql = string.Format(sbSql, id);

WITH(ROWLOCK) 可能也不需要。 99.9% 的时间 SQL Server 会执行相关的锁定,您应该只在复杂或特殊情况下显式强制某些锁定。

【讨论】:

以上是关于同时执行UPDATE时出现死锁的主要内容,如果未能解决你的问题,请参考以下文章

SQLException : 处理 2 个不同的表时出现死锁错误

访问 StackExchange.Redis 时出现死锁

核心数据 - 删除持久存储时出现死锁

使用 Rownum 时出现数据库死锁?

使用 ReadFile 和 WriteFile 时出现死锁

在页面上尝试 IX 锁定时出现 SQL 死锁