'Aurora MySQL Write Forwarding + EntityFramework; Concurrency exception and timeouts

we have an existing .net application that makes heavy use of EntityFramework (6.4.4), as well as some usage of Dapper (2.0.35) both with MySql.Data provider (8.0.23).

we are in the process of exploring how to move to a global RDS Aurora database with write forwarding, and i have been working with a minimal simulation of our application.

so far in the secondary region, inserting data with EntityFramework always fails on SaveChanges; if connection pooling is off: DbUpdateConcurrencyException: Store update, insert, or delete statement affected an unexpected number of rows (0) (i assume the concurrency here is the write-forwarding, as i am the only one using this test database). if connection pooling is on: with a timeout (i think) trying to read the affected rows.

using dapper (as a comparison), running INSERT INTO...; SELECT last_insert_id(); or INSERT INTO...; DO SLEEP(2); SELECT last_insert_id(); in a single call always returns an id of 0, while running INSERT INTO ...; in one call and then SELECT last_insert_id(); in a second call produces the correct id.

changing the value of aurora_replica_read_consistency doesn't seem to make a difference.

(in the primary region, everything works as expected - no timeouts or errors and the last_insert_id is correct)

i've been trying to play with settings, but i haven't really made any progress

i have opened an aws support case as well, but i was wondering if anyone has examples of a .net application working with write forwarding for a global aurora mysql database? especially with entityframework?

or knows of any gotchas or tips on where to focus an investigation?

=====================================

table creation:

CREATE TABLE IF NOT EXISTS `data` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Key` varchar(100) NOT NULL,
  `Value` varchar(45) DEFAULT NULL,
  `Date` datetime DEFAULT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `key_UNIQUE` (`Key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

database entity:

[Table("data")]
public class SavedData
{
   [Key]
   public int ID { get; set; }
   public string Key { get; set; }
   public string Value { get; set; }
   public DateTime Date { get; set; }
}

context:

[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class DatabaseContext : DbContext, IDbContext
{
    public DatabaseContext()
    {
        Configuration.LazyLoadingEnabled = false;
        Configuration.UseDatabaseNullSemantics = true;
        Database.SetInitializer<DatabaseContext>(null);
    }

    public virtual DbSet<SavedData> SavedData { get; set; }
}

access:

using var dbContext = new DatabaseContext();
var dbEntity = new Entities.SavedData
{
    Key = toSave.Key,
    Value = toSave.Value,
    Date = DateTime.UtcNow
};
dbContext.SavedData.Add(dbEntity);
dbContext.SaveChanges();
Console.WriteLine($"updated entity id {dbEntity.ID}");
return dbEntity.ID;

the connection string looks like (connection pooling off)

password=*****;User Id=failover_user;server=********;port=3306;database=failover_test;Pooling=false;

or (connection pooling on)

password=*****;User Id=failover_user;server=********;port=3306;database=failover_test;MinimumPoolSize=1;maximumpoolsize=5;



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source