【问题标题】:Command.ExecuteNonQuery() is hanging upCommand.ExecuteNonQuery() 挂断
【发布时间】:2014-10-01 01:55:27
【问题描述】:

当我调试存储过程时它可以工作,但我的 C# 代码在执行相同的存储过程时挂起 vai Command.ExecuteNonQuery();

当它卡住时,我也无法在相应的表上使用 select 命令。

请大家帮我看看为什么我的Command.ExecuteNonQuery(); 挂了。

这里是一些代码sn-ps

 using (command = manager.CreateStoredProcCommandWrapper(
            "UpdatePayrollStagingWithTaxYearID",
            new Object[] { HttpContext.Current.Session.SessionID, taxyearID }))
            {
                manager.ExecuteNonQuery(command);
            }


          public void ExecuteNonQuery(NTTGDBCommandWrapper commandWrapper)
        {
            NTTGArgumentValidation.CheckForNullReference(commandWrapper, "commandWrapper");
            Stack trans = GetTransactions();
            if (trans.Count > 0)
            {
                GetDatabase().ExecuteNonQuery(commandWrapper.InnerCommand, (IDbTransaction)trans.Peek());
            }
            else
            {
                GetDatabase().ExecuteNonQuery(commandWrapper.InnerCommand);
            }
        }

        protected Stack GetTransactions()
        {
            Stack transactionStack = (Stack)CallContext.GetData(this._contextIdentifierForTransactions);
            if (transactionStack == null)
            {
                transactionStack = new Stack();
                CallContext.SetData(this._contextIdentifierForTransactions, transactionStack);
            }

            return (transactionStack);
        }

        public virtual void ExecuteNonQuery(DBCommandWrapper command, IDbTransaction transaction)
        {
            PrepareCommand(command, transaction);
            DoExecuteNonQuery(command);
        }

         private void DoExecuteNonQuery(DBCommandWrapper command)
        {
            try
            {
                DateTime startTime = DateTime.Now;
                command.RowsAffected = command.Command.ExecuteNonQuery();
                this.instrumentation.CommandExecuted(startTime);
            }
            catch
            {
                this.instrumentation.CommandFailed(command.Command.CommandText, ConnectionStringNoCredentials);
                throw;
            }
        }

【问题讨论】:

  • 你能发布你的数据访问代码和sql吗?只是说 Command.ExecuteNonQuery() 挂起是没有用的。
  • 您是否尝试在从 C# 进行测试时运行 SQL 分析器以查看您的 sql server 上实际执行的命令?
  • 是的,我用 Sql Profiler 试过了,它是正确的。
  • 您是否检查过 sp_who2 以确保您的进程没有被锁定表的另一个进程阻塞?
  • 即使进行了编辑,我们也看不到参数是如何附加到 sp 调用的。

标签: c# sql-server-2008


【解决方案1】:

您似乎正在使用事务。

在您的 DoExecuteNonQuery() 方法中,当您的 sql 成功或失败时,您看起来不像是在调用 IDbTransaction.Commit()IDbTransaction.Rollback()。不这样做会导致 SQL Server 持有任何锁,直到事务以某种方式关闭,并且肯定会导致 ExecuteNonQuery() 挂起。

【讨论】:

    【解决方案2】:

    您省略了调试时需要了解的最重要部分。但是,您确实留下了一条重要线索:

    当它卡住时,我也无法在相应的表上使用 select 命令。

    这告诉我查询正在运行,而且它需要的时间太长。这至少可以让我提出一些尝试的建议:

    1. 如果您正在使用参数化查询(并且您应该这样做),您可能会遇到 Sql Server 正在缓存基于第一组参数值的次优执行计划的情况。在OPTION RECOMPILE and sp_updatestats 上阅读此问题以帮助解决此问题。
    2. 如果您使用参数化查询,并使用AddWithValue() 函数,您最终可能会遇到 .Net 从您的参数推断错误的数据库类型,因此 Sql Server 必须按行执行转换并且不能使用好的索引。 Instead, use the Add() overload that expects a specific database type.
    3. 如果您不使用查询参数,则需要开始。撇开安全问题不谈(而且它们很重要),查询参数更好,因为它们允许 Sql Server 更好地缓存查询计划,并且(撇开上述问题)产生更好的执行计划,从而加快查询速度。

    【讨论】:

    • 但是当我尝试使用相同的值调试我的 SP 时,它运行完美。
    • @SharadSingh 你如何打电话很重要。例如,如果存储过程调用 varchar 参数,并且您使用 AddWithValue() 进行设置,则最终可能会使用 nvarchar 值调用该过程,并且在错误的情况下该过程将执行每行转换和不使用索引。相同的过程,相同的值,巨大不同的执行时间。
    • 不,我们不会在应用程序的任何地方使用 AddWithValue()。
    【解决方案3】:

    我个人通过向我的命令添加参数而不是连接字符串来解决这个问题。

    command.Parameters.Add(new OracleParameter("@pParameter", pParamValue));
    

    command.Parameters.Add(new SqlParameter("@pParameter", pParamValue));
    

    ...

    希望这能有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 2011-07-05
      • 2011-04-15
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多