ASP.NET WebForms中SQL批量更新如何跳过锁定或超时行?
解决批量更新订单优先级时跳过锁定订单的方案
核心改进方向
- 捕获SQL锁超时异常,直接跳过被锁定的订单
- 优化数据库连接管理,避免频繁开关连接的开销
- 简化不必要的显式事务(单条UPDATE操作本身具备原子性)
- 记录更新失败的订单,方便后续处理
修改后的代码
// 用using自动管理连接生命周期,放在循环外减少连接开销 using (SqlConnection cnn3 = new SqlConnection(yourConnectionString)) { cnn3.Open(); // 提前定义SQL语句,避免循环中重复创建 string query = @" UPDATE DATAORDERS SET DATAORDERS.PRIORITYCODE = @PTYCODE WHERE DATAORDERS.ORDERNO = @ORDERNO"; using (SqlCommand cmd = new SqlCommand(query, cnn3)) { // 预先添加参数,循环中仅更新参数值 cmd.Parameters.Add("@PTYCODE", SqlDbType.VarChar); // 根据数据库字段类型调整 cmd.Parameters.Add("@orderno", SqlDbType.VarChar); // 根据数据库字段类型调整 cmd.CommandTimeout = 30; // 缩短超时时间,快速跳过锁定订单 List<string> failedOrders = new List<string>(); for (int i = 0; i < GridView1.Rows.Count; i++) { DropDownList PTY_CHANGE = (DropDownList)GridView1.Rows[i].FindControl("PTY_CHANGE"); string orderNo = GridView1.Rows[i].Cells[0].Text; string newPriority = PTY_CHANGE.SelectedItem.Value; try { cmd.Parameters["@PTYCODE"].Value = newPriority; cmd.Parameters["@orderno"].Value = orderNo; // 更新操作使用ExecuteNonQuery更合适,无需返回数据 cmd.ExecuteNonQuery(); } catch (SqlException ex) { // 捕获SQL Server锁超时/死锁错误码(1222=请求超时,1205=死锁牺牲品) if (ex.Number == 1222 || ex.Number == 1205) { failedOrders.Add(orderNo); continue; // 跳过当前订单,继续处理下一个 } else { // 其他SQL异常按需处理,或直接抛出 throw; } } catch (Exception ex) { // 处理控件查找失败等其他异常 failedOrders.Add(orderNo); continue; } } // 反馈失败订单给用户 if (failedOrders.Count > 0) { string message = "以下订单更新失败(可能被其他模块锁定):" + string.Join(", ", failedOrders); ClientScript.RegisterStartupScript(this.GetType(), "alert", $"alert('{message}');", true); } } }
关键说明
- 异常精准捕获:针对SQL Server特定的锁相关错误码处理,确保只跳过锁定导致的失败订单
- 资源优化:
using语句自动释放连接和命令资源,循环外创建连接避免频繁建立/断开连接的性能损耗 - 超时控制:缩短命令超时时间,避免因等待锁释放导致的长时间卡顿
- 用户反馈:收集失败订单并弹窗提示,便于后续补操作
内容的提问来源于stack exchange,提问作者kvj
相关产品推荐
相关产品推荐

