SAP B1项目SqlTransaction执行BeginTransaction时抛System.InvalidOperationException求助
SAP B1项目事务异常修复方案
问题场景
开发SAP B1项目时,已实现跨表数据迁移及原表清理逻辑,现在要通过按钮将子表已转移数据保存到SAP自定义字段,但执行SqlTransaction transaction = con.BeginTransaction();时触发System.InvalidOperationException,异常信息:invalid transaction closed the connection。
核心错误原因
启动事务前未打开数据库连接,SqlTransaction要求连接必须处于Open状态才能创建。
额外代码问题
除了事务顺序错误,代码还有以下问题:
- INSERT语句中表名使用了参数
@ODS_HFTURETIM,SQL不支持用参数指定表名,需直接写实际表名 - VALUES子句末尾多了一个冗余的右括号
- SQL语句中的参数名与代码中添加的参数名不匹配(如
@SİPARİŞ NOvs@SİPARİŞ NUMARASI) - 未过滤DataGridView中的空行,可能导致空值插入报错
- 未用
using管理连接和事务,资源释放不严谨
修复后的代码
private void button4_Click(object sender, EventArgs e) { string constring = @"Data Source = *.***.***.**; Initial Catalog = SBODemoTR; User ID = sa ; Password = *******01"; // 使用using自动管理连接资源 using (SqlConnection con = new SqlConnection(constring)) { con.Open(); // 连接打开后再启动事务 using (SqlTransaction transaction = con.BeginTransaction()) { try { foreach (DataGridViewRow row in dataGridView1.Rows) { // 过滤空行和新行 if (row.IsNewRow) continue; // 修正INSERT语句的语法和参数名 using (SqlCommand cmd = new SqlCommand(@" INSERT INTO ODS_HFTURETIM ([MÜŞTERİ], [SİPARİŞ NO], [SATIŞ NO], [KALEM TANIMI], [PLANLANAN TESLİM TARİHİ], [SİPARİŞ MİKTARI]) VALUES(@MÜŞTERİ, @SİPARİŞ_NO, @SATIŞ_NO, @KALEM_TANIMI, @PLANLANAN_TESLIM_TARIHI, @SIPARIS_MIKTARI) ", con)) { cmd.Transaction = transaction; // 统一参数名,避免不匹配,同时处理空值 cmd.Parameters.AddWithValue("@MÜŞTERİ", row.Cells["MÜŞTERİ"].Value ?? DBNull.Value); cmd.Parameters.AddWithValue("@SİPARİŞ_NO", row.Cells["SİPARİŞ NO"].Value ?? DBNull.Value); cmd.Parameters.AddWithValue("@SATIŞ_NO", row.Cells["SATIŞ NO"].Value ?? DBNull.Value); cmd.Parameters.AddWithValue("@KALEM_TANIMI", row.Cells["KALEM TANIMI"].Value ?? DBNull.Value); cmd.Parameters.AddWithValue("@PLANLANAN_TESLIM_TARIHI", row.Cells["PLANLANAN TESLİM TARİHİ"].Value ?? DBNull.Value); cmd.Parameters.AddWithValue("@SIPARIS_MIKTARI", row.Cells["SİPARİŞ MİKTARI"].Value ?? DBNull.Value); cmd.ExecuteNonQuery(); } } transaction.Commit(); MessageBox.Show("Başarılı Bir Şekilde Kaydedildi!"); } catch (Exception ex) { transaction.Rollback(); MessageBox.Show(ex.Message); } } } // using结束后自动关闭连接,无需手动调用con.Close() }
其他优化建议
- 避免使用全局SqlConnection实例(如button1_Click中的全局con),每次操作创建新连接并通过using管理,避免连接泄漏
- 使用强类型参数(如
cmd.Parameters.Add("@MÜŞTERİ", SqlDbType.NVarChar).Value = ...)代替AddWithValue,避免隐式类型转换问题 - 批量插入时可改用SqlBulkCopy提升性能,减少多次ExecuteNonQuery的开销
内容的提问来源于stack exchange,提问作者elbays
相关产品推荐
相关产品推荐

