Проблема с параллелизмом при обновлении данных в БД с использованием Quartz .NET и EF CoreC#

Место общения программистов C#
Anonymous
Проблема с параллелизмом при обновлении данных в БД с использованием Quartz .NET и EF Core

Сообщение Anonymous »

Я хочу ввести в своем приложении горизонтальное масштабирование вместо вертикального.

Сейчас мы используем Quartz .NET для фоновых задач, но в некластеризованном режиме, всего 1 экземпляр.< /p>
Итак, я обнаружил возможность горизонтального масштабирования с помощью кластеризации. Затем настроил его в тестовом приложении и обнаружил, что два экземпляра просто участвуют в «крысиных бегах» и дважды обновляют каждую строку.
Есть идеи, как можно разделить нагрузку между многими экземплярами с помощью кварца и ядра ef? Как я могу «заблокировать» строки в БД, чтобы другие экземпляры не могли работать с ними и брать следующий пакет.
Код, который я использую для обновления БД, и код задания Quartz приведены ниже.< /p>
public async Task UpdateNameAndMarkHiddenLogsAfterReachingDate(DateTime date)
{
const int batchSize = 10;
int hidden = 0;
int hiddenInThisLoopCycle;

using (var transaction = await _context.Database.BeginTransactionAsync())
{
try
{
do
{
var logs = await _context.Logs
.Where(l => l.Created < date && l.IsHidden == false)
.Take(batchSize).ToListAsync();

foreach (var log in logs)
{
log.Message = "UpdatedLog";
log.IsHidden = true;

log.LogDetails.Add(new LogDetail()
{
ChangedByThread = Environment.CurrentManagedThreadId.ToString(),
LastChanged = DateTime.UtcNow,
Name = Thread.CurrentThread.Name
});
}

var result = await _context.SaveChangesAsync();

hiddenInThisLoopCycle = result;

Console.WriteLine($"Deleted {hiddenInThisLoopCycle} logs.");
hidden += hiddenInThisLoopCycle;
Console.WriteLine($"Hidden: {hiddenInThisLoopCycle}");
} while (hiddenInThisLoopCycle > 0);

await transaction.CommitAsync();
}
catch (Exception ex)
{
await transaction.RollbackAsync();
Console.WriteLine($"Transaction failed: {ex.Message}");
throw;
}
}

return hidden;
}

[DisallowConcurrentExecution]
public class DeleteLogsJob : IJob
{
private readonly ILogRepository _logRepository;
private readonly DateTime _date;
private readonly ILogger _logger;

public DeleteLogsJob(ILogRepository logRepository, IOptions options, ILogger logger)
{
_logRepository = logRepository;
_date = options.Value.DeleteAfterDate ?? throw new ArgumentException("DeleteAfterDate was not found in configuration");
_logger = logger;
}

public async Task Execute(IJobExecutionContext context)
{
_logger.LogInformation("About to delete old logs from the database");
var logsDeleted = await _logRepository.UpdateNameAndMarkHiddenLogsAfterReachingDate(_date);
_logger.LogInformation("Deleted {0} old logs from the database", logsDeleted.ToString());
}
}


Подробнее здесь: https://stackoverflow.com/questions/787 ... nd-ef-core

Вернуться в «C#»