Java 事务(进程ID)在与另一个进程的锁通信缓冲区资源上被死锁,并被选为死锁受害者

Java 事务(进程ID)在与另一个进程的锁通信缓冲区资源上被死锁,并被选为死锁受害者,java,sql-server,coldfusion,Java,Sql Server,Coldfusion,我有一个用MS SQL更新表的java程序。web用户也可以通过ColdFusion中创建的网站访问此表 最近,我遇到以下错误: sql_stmt.executeUpdate("update random_selection " + "set forecasted = 1 where " + " randnum = " + ora_rs.getString("RANDNUM") + " and quarter = " + quarter + " and ozip3

我有一个用MS SQL更新表的java程序。web用户也可以通过ColdFusion中创建的网站访问此表

最近,我遇到以下错误:

sql_stmt.executeUpdate("update random_selection "
    + "set forecasted = 1 where "
    + " randnum = " + ora_rs.getString("RANDNUM")
    + " and quarter = " + quarter
    + " and ozip3 = " + ora_rs.getString("OZIP3"));
出错的CF查询是:

<cfquery name="submit_forecast" datasource="ttmsdropper" username="#request.db_username#" password="#request.db_password#">
    INSERT INTO forecast_entry
    VALUES (<cfqueryparam value="#currentRecord[8]#">)
</cfquery>

插入到forecast_条目中
值()

导致此错误的原因是什么?如何修复此错误?

当两个进程试图同时命中相同的数据时,会发生死锁-两个进程对数据的声明相同。当有大量的更新/插入活动正在进行时(如您所述),这种情况最为常见。DB系统“选择”其中一项交易为“赢家”

在某些情况下,通过索引可以改善或缓解死锁,但只有在涉及到选择的情况下,良好的索引策略可能会提高选择的性能并使行锁定更加有效。但是,如果死锁来自与更新争用的插入,索引将没有帮助。实际上,主动索引可能会降低这种情况,因为索引必须随着数据插入或更新而更新


如何解决它在很大程度上取决于您的系统和您正在尝试做什么。您必须最小化插入/更新锁定,或者以某种方式提供更多或更快的资源。将插入绑定在一起并对其进行批处理、更多的进程或RAM(有时——不总是)、集群、拆分表和数据、微调并行性——这些都是可行的选择。而且没有硬性规定。

如果表从未更新(仅插入),则您可能希望尝试将选择更改为-在CFTransaction ReadUncommitted中没有锁定或包装选择


正如Mark所说,这是一个DB错误,而不是ColdFusion和锁正在发生。如果有复杂的选择和更新,请在子句列中添加索引。

我考虑过这个建议-好建议。我刚刚得到的印象是,他基于java的“更新”妨碍了他基于CF的“插入”:(为了向任何可能看到这篇文章的人澄清,死锁不会发生在一个争论点上。只有当(至少)存在两个争用点,并且一个进程先锁定一个,然后另一个,并且其他进程以相反的顺序锁定它们时,才会发生这种情况。参见的定义。