同时执行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时出现死锁的主要内容,如果未能解决你的问题,请参考以下文章