Search code examples
c#azure-sql-databasedapper

Why given code is generating 'The request limit for the database is X' with Azure SQL


I have code running in an Azure Functions Consumption Plan. My database is limited to 60 concurrent logins, which seems to be causing this error:

The request limit for the database is X

My question is: why is this loop within the transaction hitting this limit? Is one transaction considered one request, or not? I know the code is of poor quality, but that's only because I was experimenting with hardcore solutions during my exploration.

SOME_QUERY1 = "INSERT INTO SomeTable (p1,p2,p3,p4) Values (p1,p2,p3,p4); SELECT CAST(SCOPE_IDENTITY() as int)";
SOME_QUERY2 = "INSERT INTO OtherTable (10 fields)"; 

public async Task<IEnumerable<string>> SaveBusinessTransaction(TransactionBatchEntity businessEntity)
{
    using (var connection = new SqlConnection(_connectionString))
    {
        connection.Open();
        var successfullyAddedTransactions = new List<string>();

        using (var transaction = connection.BeginTransaction())
        {
            try
            {
                var transactionId = (await connection.QueryAsync<int>(SOME_QUERY1, new { Paramter = 1 }, transaction)).Single();

                foreach (var details in businessEntity.Details)
                {
                    var detailsEntity = new
                    {
                        //some fields
                    };

                    await connection.ExecuteAsync(SOME_QUERY2, detailsEntity, transaction);
                    successfullyAddedTransactions.Add(detailsEntity.TransactionNumber);
                }

                transaction.Commit();

                return successfullyAddedTransactions;
            }
            catch (Exception)
            {
                transaction.Rollback();
                connection.Close();
                throw;
            }
        }
    }
}

EDIT:

IMPORTANT: Missing part involving an execution context.

transactions.ForEach(t => _sqlService.SaveBusinessTransaction(t));

Solution

  • After some digging, I discovered the reason, unfortunately, one level above.

    transactions.ForEach(t => _sqlService.SaveBusinessTransaction(t));
    

    As we can see, this is a fire-and-forget approach. A temporary solution was obvious:

    transactions.ForEach(t => await _sqlService.SaveBusinessTransaction(t));
    

    The long-term solution is to change the database schema, but that is outside the scope of this answer.