Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseMySql' call

12,023
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=EFMiscellanous.ConnectionResiliency;Trusted_Connection=True;ConnectRetryCount=0",
            options => options.EnableRetryOnFailure());
}
Share:
12,023
N.Ayaz
Author by

N.Ayaz

Updated on June 04, 2022

Comments

  • N.Ayaz
    N.Ayaz almost 2 years

    I have an application based on F#, and I use EF-Core and MySQL (Pomelo.EntityFrameworkCore.MySql). I have an async method which updates data in DB(MySql)

    let updatePlayerAchievementsAsync (logger:ILogger) (ctx:ReportCacheDbContext) (id: int) = async {
      let! account = ctx.AccountCaches.FirstOrDefaultAsync(fun e -> e.AccountId = id) |> Async.AwaitTask
      if account <> null then
        account.State <- "Closed"
        do! ctx.SaveChangesAsync true |> Async.AwaitTask |> Async.Ignore
        logger.LogInformation("Account{0} updated", id)        
    }
    

    when this method comes to the 99th element, the following errors occurred:

    |ERROR|System.InvalidOperationException:An exception has been raised that is likely due to a transient failure. Consider enabling transient error resiliency by adding 'EnableRetryOnFailure()' to the 'UseMySql' call. 
    ---> MySql.Data.MySqlClient.MySqlException (0x80004005): Connect Timeout expired. All pooled connections are in use.
    

    I tried to follow 1st error's recomendation and tried to add EnableRetryOnFailure()

    member this.ConfigureServices(services: IServiceCollection) =
        services.AddOptions() |> ignore
        services.AddCors() |> ignore
        
        services
            .AddDbContext<ApplicationDbContext>(
                fun (service:IServiceProvider) (dbContext:DbContextOptionsBuilder) ->
                    dbContext.UseMySql(profile.DbConnectionToAdmin /*HERE*/)|> ignore)
        ...
    

    And I can't find any documentation about this adding options for F# & MySQL, cause all found info written on C#. Maybe problem in used pools (default max=100) and I wrote next:

    ...
    do! ctx.SaveChangesAsync true |> Async.AwaitTask |> Async.Ignore
    ctx.Database.CloseConnection()
    logger.LogInformation("Account{0} updated", id)  
    

    But anyway problem wasn't solved. This is my new experience in F# and async and I cant understand what I did incorrectly. Could anyone help me in such problem? Thanks a lot!