我有一个更新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>
导致此错误的原因是什么?如何解决?
答案 0 :(得分:12)
当2个进程试图同时访问相同的数据时发生死锁 - 两者都对数据具有相同的声明。当正在进行大量更新/插入活动时(如您所述),这是最常见的。数据库系统“选择”其中一个交易成为“赢家”。
在某些情况下,可以通过索引来改进或减轻死锁,但仅在涉及选择时 - 一个好的索引策略可能会提高选择性能并使行锁定更有效。但是,如果死锁来自与更新竞争的插入,则索引将无济于事。事实上,积极的索引可能会降低情况,因为索引必须随数据插入或更新一起更新。
如何解决这个问题在很大程度上取决于您的系统以及您要做的事情。您必须最小化插入/更新锁定或以某种方式提供更多或更快的资源。将插入物捆绑在一起并对它们进行批处理,更多处理或RAM(有时 - 并非总是如此),聚类,拆分表和数据,微调并行性 - 这些都是可行的选择。而且没有硬性规定。
答案 1 :(得分:1)
如果永远不会更新表(仅插入),那么您可能想尝试将选择更改为 - 在cftransation readuncommited中没有锁定或包装选择。
正如Mark所说,这是一个数据库错误,而不是ColdFusion并且正在进行锁定。如果有复杂的选择和更新,请在子句列中添加添加索引。