Error detail : Randomly getting Timeout expired error when using Active Directory Managed Identity authentication with a user-assigned managed identity with Microsoft.Data.SqlClient 5.1.1 library in Azure SQL DB. It’s working fine with SQL authentication.
Error :
The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.***
Application Detail:
Frontend Application: ASP.NET MVC 6 C# ;
ORM: Entity Framework 6 ;
Database: Azure SQL DB ;
App Deployed: Azure Web APPS;
Lib Version: Microsoft.Data.SqlClient 5.1.1
Exception:
System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
at Microsoft.Data.SqlClient.SqlConnection.Open()
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.OpenDbConnection(Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.Enumerator.<>c.<MoveNext>b__19_0(DbContext _, Enumerator enumerator)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<>c__DisplayClass31_0`2.<Execute>b__0(DbContext context, TState state)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementation[TState,TResult](Func`3 operation, Func`3 verifySucceeded, TState state)
at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.Enumerator.MoveNext()
</Data>
</EventData>
</Event>
</Events>
We follow this link to implement SQL Azure AD authentication
Connection String:
Server=tcp:**\<ServerName\>**.database.windows.net,1433;Initial Catalog=\<**DBNAME**\>;Persist Security Info=False;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=300;Min Pool Size=0;Max Pool Size=2024;Pooling=True;Authentication=Active Directory Managed Identity;User Id=\<**MI Object Id**\>
Code:
Startup code:
class Startup
{
services.AddDbContext<MYDBContext>(m => m.UseSqlServer(conString, sqlServerOptionsAction: o => o.EnableRetryOnFailure()));
services.AddTransient<IPageRepository, PageRepository>();
}
An Example for SP call:
class PageRepository
{
public PageRepository(MYDBContext context) : base(context)
{
_context = context;
}
public Page? GetPage(string pageUrl, Guid eventId, Guid phaseId, string releaseAuthtoken = "")
{
string sql = "EXECUTE [Admin].[uspGetPage] @PageUrl,@EventId,@PhaseId,@ReleaseAuthtoken";
List<SqlParameter> parms = new List<SqlParameter>()
{
new SqlParameter("@PageUrl",pageUrl),
new SqlParameter("@EventId", eventId),
new SqlParameter("@PhaseId", phaseId),
new SqlParameter("@ReleaseAuthtoken", releaseAuthtoken),
};
var page = _context.Page.FromSqlRaw<Page>(sql, parms.ToArray()).AsEnumerable<Page>();
return page.FirstOrDefault();
}
}
I tried disabling the query tracking behaviors as we have only read operation in our Application
UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
It's not working How can I solve this?