6

我有一个更新 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>

是什么导致了这个错误,我该如何解决?

4

2 回答 2

12

当 2 个进程尝试同时访问相同的数据时,就会发生死锁 - 两者都对数据具有相同的要求。当进行大量更新/插入活动时(如您所描述的),这是最常见的。数据库系统“选择”其中一个交易作为“赢家”。

在某些情况下,可以通过索引来改善或减轻死锁,但只有在涉及到选择时——一个好的索引策略可能会提高选择性能并使行锁定更有效。但是,在死锁来自与更新竞争的插入的情况下,索引将无济于事。事实上,激进的索引可能会降低这种情况,因为索引必须与数据插入或更新一起更新。

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

于 2012-06-06T15:12:48.550 回答
1

如果从不更新表(只有插入),那么您可能想尝试将选择更改为 - 没有锁定或在 cftransation readuncommited 中包装选择。

正如马克所说,这是一个数据库错误,而不是 ColdFusion 并且正在发生锁定。如果有复杂的选择和更新,请向子句列添加索引。

于 2012-06-06T22:19:33.367 回答