You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:35:25