在同时执行更新时出现死锁问题

3

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

请问有人能给我一些解决死锁问题的建议吗?提前感谢您。

SampleController:

onSubmit(userAccount)
{
     sampleBO.testDeadLock(userAccount.getUserAccountId());

}

样本业务对象:

public void testInsert(Long id)
{
    sampleDAO.testInsert4(id);      
}

public void testDeadLock(Long id)
{
    testInsert(id);
    sampleDAO.testUpdate4(id);  
}

样例DAO:

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());
}

1
什么品牌和版本的SQL? - RBarryYoung
1
此外,请发布表定义,包括任何键、索引、约束和/或触发器,因为问题很有可能就在那里。 - RBarryYoung
我有什么遗漏吗?看起来你正在同步调用两个执行,所以在插入完成之前,testUpdate4调用不应该触发。 - Kir
嗨,我不确定你是否遇到了死锁问题,因为你的代码不够复杂以致于引起死锁。你能否描述一下你认为自己陷入死锁的原因、收到的错误信息以及最重要的是你使用的 SQL 方言是什么? - itayw
1个回答

0

如果发生死锁,则不是由您提供的代码引起的,除非:

  • 您同时运行了多个此测试程序的实例。
  • 上述代码正在异步运行-但似乎不是这种情况。
  • 在运行这些测试时,数据库中有其他活动。

我认为最后一个原因是造成死锁的罪魁祸首。

您可以通过执行SQL跟踪并确定确切运行时间和内容来查明发生死锁的原因。


每个人有自己的喜好,但你知道吗?你可以像这样声明你的SQL查询。@符号允许文本跨多行,并且转义特殊字符,如反斜杠。
string sbSql = @"
    INSERT INTO Test (id, note)
    VALUES ({0}, 'test')";

sbSql = string.Format(sbSql, id);

WITH(ROWLOCK) 也许也不是必需的。99.9% 的情况下,SQL Server 将执行相关锁定,您只应在复杂或非常规情况下明确强制某些锁定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接