.NET Core Consumer Kafka error deadlock SQL Server

98 views Asked by At

I am new to .NET. I have micro services using .NET Core. This service is used to become a Kafka consumer. In the consumer function there is a function to insert into the SQL Server database. This function often experiences deadlock errors, but sometime when traffic is low this code work with no error. I attached the function code. This function is simple, just to insert into the database using the transaction set identity insert on. Please help if anyone has experienced something like this. The error looks like this.

An exception occurred in the database while saving changes for context type 'Entities.RepositoryContext'.
      Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
       ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Transaction (Process ID 414) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
    private async Task insertData(Dto data)
    {
        var dataFromDB = _repository.myRepo.FirstOrDefaultWithNoLock(p => p.ID.Equals(data.ID));

        if (dataFromDB == null)
        {
            dataFromDB = _mapper.Map<Model>(data);
            _repository.myRepo.Create(dataFromDB);
            _repository.myRepo.SaveChangesWithIdentityInsert();
            return;
        }

        return;
    }

I attached code inside SaveChangesWithIdentityInsert

        public static void EnableIdentityInsert<T>(this DbContext context) => SetIdentityInsert<T>(context, true);
        public static void DisableIdentityInsert<T>(this DbContext context) => SetIdentityInsert<T>(context, false);

        private static void SetIdentityInsert<T>([NotNull] DbContext context, bool enable)
        {
            if (context == null) throw new ArgumentNullException(nameof(context));
            var entityType = context.Model.FindEntityType(typeof(T));
            var value = enable ? "ON" : "OFF";
            context.Database.ExecuteSqlRaw($"SET IDENTITY_INSERT dbo.{entityType.GetTableName()} {value}");
        }

        public static void SaveChangesWithIdentityInsert<T>([NotNull] this DbContext context)
        {
            if (context == null) throw new ArgumentNullException(nameof(context));
            var strategy = context.Database.CreateExecutionStrategy();
            strategy.Execute(
            () =>
            {
                using var transaction = context.Database.BeginTransaction(isolationLevel: System.Data.IsolationLevel.ReadUncommitted);
                context.EnableIdentityInsert<T>();
                context.SaveChanges();
                context.DisableIdentityInsert<T>();
                transaction.Commit();
            });
            context.ChangeTracker.Clear();
        }

I have try to use with no lock. I have searching to auto retry consumer when deadlock occur but not found anything.

0

There are 0 answers