System.InvalidOperationException异常:Commit阶段报错的非WebConfig解决方案咨询
解决Commit时触发的System.InvalidOperationException异常(无需修改WebConfig)
执行代码到Commit步骤时触发以下异常:
System.InvalidOperationException: 'Invalid operation given the current state of the object.'
已知修改WebConfig的appsettings段可解决问题,但寻求无需修改配置的方案。
报错位置代码
public ErrorCode insertNC(EntidadesNC data) { var errorCode = new ErrorCode(); DbConnection DataConnection = ConnectionGet(enuTypeDataBase.OracleVTime); DbTransaction tran = null; try { DataConnection.Open(); tran = DataConnection.BeginTransaction(); foreach (var item in data.ListainsertNC) { if (errorCode.P_COD_ERR == 0) { errorCode = insertNCV2(item, DataConnection, tran); } } } catch (Exception ex) { errorCode.P_COD_ERR = 1; errorCode.P_MESSAGE = ex.ToString(); ELog.save(this, ex.ToString()); } finally { if (errorCode.P_COD_ERR == 0) { tran.Commit(); } else { tran.Rollback(); } if (DataConnection.State == ConnectionState.Open) DataConnection.Close(); } return errorCode; }
被调用的insertNCV2方法代码
public ErrorCode insertNCV2(itemNC data, DbConnection connection, DbTransaction tran) { List<OracleParameter> parameter = new List<OracleParameter>(); var response = new itemNC(); var errorCode = new ErrorCode(); var sPackageName = ProcedureName.pkg_paymentNC + ".SP_PRUEBA_PAYROLL"; try { parameter.Add(new OracleParameter("P_NID_COTIZACION", OracleDbType.Int64, data.P_NID_COTIZACION, ParameterDirection.Input)); parameter.Add(new OracleParameter("P_NRECEIPT", OracleDbType.Varchar2, data.P_NRECEIPT, ParameterDirection.Input)); parameter.Add(new OracleParameter("P_SCODCHANNEL", OracleDbType.Int64, data.P_SCODCHANNEL, ParameterDirection.Input)); //OUTPUT OracleParameter P_COD_ERR = new OracleParameter("P_COD_ERR", OracleDbType.Int32, 9000, errorCode.P_COD_ERR, ParameterDirection.Output); OracleParameter P_MESSAGE = new OracleParameter("P_MESSAGE", OracleDbType.Varchar2, 900, errorCode.P_MESSAGE, ParameterDirection.Output); parameter.Add(P_COD_ERR); parameter.Add(P_MESSAGE); OracleDataReader odr = (OracleDataReader)this.ExecuteByStoredProcedureVT(sPackageName, parameter); // ELog.CloseConnection(odr); } catch (Exception ex) { errorCode.P_COD_ERR = 1; errorCode.P_MESSAGE = "Hubo un error al insertar los sub items de las coberturas"; // ex.ToString(); ELog.save(this, ex.ToString()); } return errorCode; }
无需修改WebConfig的解决办法
1. 关闭未释放的OracleDataReader
insertNCV2中获取的OracleDataReader未关闭,会占用数据库连接,导致事务状态异常。使用using语句自动释放资源:
// 修改insertNCV2中的DataReader代码 using (OracleDataReader odr = (OracleDataReader)this.ExecuteByStoredProcedureVT(sPackageName, parameter)) { // 若需读取存储过程返回数据,在此处理 }
2. 关联事务到存储过程执行
insertNCV2接收了tran参数,但未关联到存储过程的执行命令中。需确保ExecuteByStoredProcedureVT内部创建的DbCommand绑定事务:
// 在ExecuteByStoredProcedureVT方法内部添加事务绑定 command.Transaction = tran;
3. 增加事务null判断
finally块中操作事务前,先判断tran是否为null(例如连接打开失败时tran未初始化),避免无效操作:
// 修改insertNC的finally块 finally { if (tran != null) { if (errorCode.P_COD_ERR == 0) { tran.Commit(); } else { tran.Rollback(); } } if (DataConnection != null && DataConnection.State == ConnectionState.Open) DataConnection.Close(); }
4. 读取存储过程输出参数值
当前代码未将存储过程的输出参数值赋值到errorCode,可能导致错误状态判断失效。在关闭DataReader后读取输出参数:
// 在insertNCV2的using块后添加 errorCode.P_COD_ERR = (int)P_COD_ERR.Value; errorCode.P_MESSAGE = P_MESSAGE.Value?.ToString() ?? string.Empty;
内容的提问来源于stack exchange,提问作者AnthonyVS
相关产品推荐
相关产品推荐

