Quantcast
Channel: SQL Server Database Engine forum
Viewing all articles
Browse latest Browse all 12963

Timeout error while reading and updating in batches in a single transaction

$
0
0

Problem:-

In a transaction I do read and update to the database in batches. First batch it runs fine and for second batch it get hanged at

sqlCommand.ExecuteReader(). The following is not my complete code but required bits of it which will give more information about the problem. At the end of this post please find the error log. Please help me.

My guess:-

The problem i see here is with the locks acquired while reading and update still remain when it comes for the second batch which is blocking the next read. But could not find a way to solve it.

  1. Get connection and open it.
  2. Begin Transaction.

    sqlUpdateTransaction = sqlUpdateConnection.BeginTransaction(String.Format("UpdateUsageDetailTransaction{0}", storageClassId))

  3. Get application lock.

    GetApplock
    {
    const String sqlText = @"DECLARE @result int EXEC @result = sp_getapplock Resource=@resourceName,@LockMode='Exclusive',@LockOwner='Transaction',@LockTimeout=@timeout select @result";

    using (SqlCommand sqlCommand = sqlTransaction.Connection.CreateCommand())
    {
    sqlCommand.CommandText = sqlText;
    sqlCommand.Parameters.AddWithValue("@resourceName", resourceName);
    sqlCommand.Parameters.AddWithValue("@timeout", milliSecondsTimeout);
    sqlCommand.CommandTimeout = secondsTimeout;
    sqlCommand.Transaction = sqlTransaction;
    Int32 lockResult = (Int32) sqlCommand.ExecuteScalar();
    }

    }

  4. Seek and read the range of records.

    using (var sqlReadConnection = new SqlConnection(_connectionString))
    {
    sqlReadConnection.Open();
    SqlTransaction sqlTransaction = _sqlUpdateTransaction;
    _cdrList = CdrOps.FetchByrecordsIdRange(_yearMonth, firstSkid, firstSkid + count - 1, sqlReadConnection);
    sqlReadConnection.Close();
    return _cdrList.Count > 0;
    }

    static public Dictionary FetchByrecordsIdRange(Int32 yearMonth, Int64 startCdrId, Int64 endCdrId, SqlConnection sqlConnection)
    {
    Dictionary cdrList = new Dictionary();
    using (SqlCommand sqlCommand = sqlConnection.CreateCommand())
    {
    sqlCommand.CommandText = "EXEC P_GetCDRData @yearMonth, @startCdrId, @endCdrID";
    sqlCommand.Parameters.AddWithValue("@yearMonth", yearMonth);
    sqlCommand.Parameters.AddWithValue("@startCdrId", startCdrId);
    sqlCommand.Parameters.AddWithValue("@endCdrID", endCdrId);
    sqlCommand.CommandTimeout = DbOps.TwoHourTimeoutValue;

    using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader())
    {
    FetchrecordPieces(sqlDataReader, cdrList);
    }
    }
    return cdrList;
    }

  5. Update the records to the list by using a loop Go and check if the number of records read is equal to the batch size then write and flush.

    update()
    {
    _tollUpdatedList.Add((Toll) record);
    _legacyUpdateCount++;
    }

  6. Dispose.

    Dipose()
    {
    if (_sqlUpdateTransaction != null && _sqlUpdateTransaction.Connection != null)
    {
    sqlUpdateTransaction.Rollback(String.Format("UpdateUsageDetailTransaction{0}", _storageClassId));
    _sqlUpdateTransaction.Dispose();
    _sqlUpdateTransaction = null;
    }

  7. Commit.

    commit()
    {
    if(_sqlUpdateTransaction != null)
    {
    _sqlUpdateTransaction.Commit();
    _sqlUpdateTransaction.Dispose();
    _sqlUpdateTransaction = null;
    }
    }

  8. Error log.
    Error: [0x80004005] MonthlyFileDb::Seek - Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.


Viewing all articles
Browse latest Browse all 12963

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>