【问题标题】:Getting timeout errors with SqlTransaction on same table在同一张表上使用 SqlTransaction 获取超时错误
【发布时间】:2013-10-17 08:53:37
【问题描述】:
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();
            }

【问题讨论】:

    标签: c# sqlcommand timeoutexception sqlparameter sqltransaction


    【解决方案1】:

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

    你可以用你的 ConnString 做到这一点:

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

    【讨论】:

    • 我会尝试的.. 但是我在做什么有什么问题吗?尤其是 sqltransaction 进程启动,然后在同一张表上,我查询?
    • 嵌套事务并非闻所未闻-但在您的情况下,如果抛出异常,您只需要一个外部事务,您将回滚所有事务。您可以删除命令行 command_serial.Transaction = InsertUpdateSerialNumbers;来自 CheckSerialNumber 方法。
    • 如果我针对命令(确实插入)删除 InsertUpdateSerialNumbers,那么当出现故障或错误时它如何回滚?在少数例外情况下,我确实在程序中回滚。
    【解决方案2】:

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

    开始:

    1. 将 command_serial_new 查询设置为:

    SELECT 1 FROM YSL00 WITH (NOLOCK) WHERE SERLNMBR = @slnr

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

    【讨论】:

    • 我会检查 1 点和 2 点。至于 3,我之前只有一个连接,但 executescalar 语句将无法工作归咎于连接。然后我为 executescalar 打开了另一个连接。
    • 其实和p.0一样。我会使用 conn.Open() 和 conn_new.Open() 打开 SqlConnections。
    • 我尝试使用 using 语句进行连接,但代码/业务逻辑在打开和关闭中跨越多行(我的意思是使用的最后一行)。但我确实关闭了原始帖子中更新的连接。
    【解决方案3】:

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

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

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

    【讨论】:

    • 我开始使用,但我遇到的问题是我将为读取的每一行打开连接。我仍在考虑如何适应上述情况。
    【解决方案4】:

    如果我没记错的话,您需要将文件内容与表格内容合并。 为此,我会推荐你​​

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

    【讨论】:

    • 我不做合并。我将更新一些表格,包括生成一些 XML 文件。
    猜你喜欢
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多