在同一个表上使用SqlTransaction获取超时错误

时间:2013-10-09 20:04:03

标签: c# sqlcommand timeoutexception sqlparameters sqltransaction

public TransImport()
{
    ConnString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;

    SqlConnection conn_new;
    SqlCommand command_serial_new;

    SqlConnection conn;
    SqlCommand command_serial;

    SqlTransaction InsertUpdateSerialNumbers;

    conn = new SqlConnection(ConnString);
    command_serial = conn.CreateCommand();

    conn_new = new SqlConnection(ConnString);
    command_serial_new = conn_new.CreateCommand();
    command_serial_new.CommandText = "SELECT 1 FROM YSL00 WHERE SERLNMBR = @slnr";
    var p = new SqlParameter("@slnr", SqlDbType.NVarChar, 50);
    command_serial_new.Parameters.Add(p);

    //Here you will start reading flat file to get serialnumber. 

     InsertUpdateSerialNumbers = conn.BeginTransaction();
     while (!headerFileReader.EndOfStream)
     {
         headerRow = headerFileReader.ReadLine();

         if (CheckSerialNumber(headerFields[0].Trim()))
            DisplayMessage("Good serialnumber"); //this function is not copied here.
      }
      InsertUpdateSerialNumbers.Commit();

}

private Boolean CheckSerialNumber(string SerialNumber)
{
    command_serial_new.Parameters["@slnr"].Value = SerialNumber;
    try
    {
        var itExists = Convert.ToInt32(command_serial_new.ExecuteScalar()) > 0;
        if (!itExists)
        {
            command_serial.Transaction = InsertUpdateSerialNumbers;
            command_serial.CommandText = "INSERT INTO YSL00([Manifest_Number],[PONUMBER],[ITEMNMBR],[SERLNMBR]"
             + "VALUES ('" + Manifest + "','" + PONr + "','" + itemNumber + "','" + serialNr  + "')";
    var insertStatus = command_serial.ExecuteNonQuery();
            return true;
        }
    }
    catch (Exception ex)
    {
        LogException(ex, "Error in CheckSerialNumber =>"+ command_serial_new.CommandText.ToString());
    }
    return false;
}

我收到错误“超时已过期。操作完成之前经过的超时时间或服务器没有响应”。

CheckSerialNumber函数也对YSL00进行了插入(我执行了标量的同一个表。请参阅上面的代码)。 正如我前面提到的,我读取并更新YSL000表的平面文件中有1000行。

请注意,我有两个单独的sqlcommands,还有两个单独的连接来处理这个问题。原因是sqltransaction它不允许我在同一个表上查询。我认为超时可能因此而发生?

感谢阅读。请建议

更新1:由于我没有粘贴整个代码,我想提一下,使用程序中的以下代码完成dispose。

            if (conn != null)
            {
                conn.Close();
                conn.Dispose();
            }

            if (conn_new != null)
            {
                conn_new.Close();
                conn_new.Dispose();
            }

4 个答案:

答案 0 :(得分:1)

您可以增加SqlConnection对象的时间。

您可以使用ConnString执行此操作:

 string connStr = "Data Source=(local);Initial Catalog=AdventureWorks;Integrated   
 Security=SSPI;Connection Timeout=300";

答案 1 :(得分:1)

我认为默认隔离级别 - 读取提交 - 阻止您的“CheckSerialNumber”方法生效。 Command_serial_new不会考虑在循环中插入的行 - 这可能会导致一些麻烦。说实话,我也会寻找一些僵局。也许command_serial_new实际上完全被另一个事务阻止了。

开始:

  1. 将command_serial_new查询设置为:
  2. SELECT 1 FROM YSL00 WITH (NOLOCK) WHERE SERLNMBR = @slnr

    1. 考虑使用较低的隔离级别来查询插入的行(将其设置为uncommited)。
    2. 关闭您的连接和交易。
    3. 只使用一个SqlConnection - 您不需要其中两个。

答案 2 :(得分:0)

您使用的许多对象实现IDisposable,您应该使用using statements包装它们。如果没有这些使用语句,.NET不一定会在垃圾收集器运行时确定的时间之前删除您的对象,并且如果它仍然在某处打开事务,则可能会阻止后续查询。

因此,例如,您需要使用using语句包装您的连接:

    using (conn_new = new SqlConnection(ConnString)) {
        ...

答案 3 :(得分:0)

如果我没有弄错,您需要将文件内容与表格内容合并。 为此我建议你

  1. 将文件内容复制到临时表(请参阅临时表 BulkInsert
  2. 使用命令 MERGE http://msdn.microsoft.com/en-us/library/bb510625.aspx)将临时表内容与原始表合并