Search code examples
c#sqlcommandtimeoutexceptionsqlparametersqltransaction

Getting timeout errors with SqlTransaction on same table


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;
}

I get error "Timeout expired. The timeout period elapsed prior to completion of the operation or server is not responding".

The CheckSerialNumber function also does an insert to YSL00 (the same table where I had executescalar. See code above). As I mentioned earlier there are 1000s of line in a flat file that I read and update YSL000 table.

Note that I have two separate sqlcommands and also two separate connections to handle this. Reason is with sqltransaction it doesn't let me to query on the same table. I think timeout may be happening because of this?

Thanks for reading. Please suggest

Update 1: Since I have not pasted entire code, I want to mention that dispose is done using below code in the program.

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

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

Solution

  • I think default isolation level - read commited - is preventing your 'CheckSerialNumber' method from being effective. Command_serial_new will not take into consideration rows inserted in your loop - this might lead to some troubles. To be honest I would also look for some deadlock. Perhaps command_serial_new is actually completely blocked by the other transaction.

    To start off:

    1. Set command_serial_new query as:

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

    1. Think about using lower isolation level to query inserted rows as well (set it to read uncommited).
    2. Close your connections and transactions.
    3. Use just one SqlConnection - you don't need two of them.