У меня есть код, который я использую для минимизации проблем параллелизма. Он структурирован примерно так:Обнаружение проблем параллелизма в Entity Framework с использованием транзакций
// HasConcurrencyIssues opens a new EntityContext and gets the actual current
// details and then compares it to what was loaded for the form
if (this.HasConcurrencyIssues()) {
// can't save, exit out of save code
return;
}
using (EntityContext context = new EntityContext()) {
// shared locks to avoid dirty reads - should I be using this?
IsolationLevel level = IsolationLevel.ReadCommitted;
using (DbContextTransaction trans == context.Database.BeginTransaction(level)) {
try {
// here is where I save stuff using the context by adding
// items to the DbSets
this.SaveStuff(context);
// execute the generated SQL commands before secondary check because
// this could take some time
context.SaveChanges();
// check again in case something happened after executing SaveChanges()
// ** gets blocked here **
if (this.HasConcurrencyIssues()) {
// can't save, rollback and exit out of save code
trans.Rollback();
return;
}
trans.Commit();
} catch (Exception ex) {
// handle error
trans.Rollback();
}
}
}
Я использовал эту структуру, чтобы минимизировать проблемы параллелизма. Проблема, с которой я сталкиваюсь, заключается в том, что я не совсем понимаю, как работают ReadCommitted
и параллелизм. Я заметил, что при второй проверке проблем параллелизма он блокируется, потому что он не может читать текущие записи (я предполагаю, что это связано с моим выбранным IsolationLevel
). Я беспокоюсь, что если я удалю эту вторичную проверку, это может привести к фантомным данным, которые я не хочу.
Приложение масштабируется и должно обрабатывать ~ 200 пользователей, которые потенциально могут захотеть отредактировать один и тот же объект и сохранить его. Я в основном хочу жесткую остановку, которая проверяет, изменился ли объект и если он есть, предотвратить сохранение.
Как я могу структурировать свой код сохранения, чтобы минимизировать проблемы параллелизма?
Редактировать
Я понимаю, что это время заблокирован, так как проверка после SaveChanges
вызова. Если я поместил вторичную проверку перед вызовом SaveChanges
, это сработает, но возможно ли, что транзакция может завершиться во время ее сохранения, что должно вызвать проблему параллелизма, но не будет?
Соответствующая архитектура системы:
Entity Framework 6
SQL Server 2012
Кажется, что обнаружение и предотвращение проблем с параллелизмом обычно лучше всего оставить в базе данных и обработке транзакций. Можете ли вы объяснить, какие проблемы параллелизма вы пытаетесь избежать, и почему вы не можете просто использовать простой «TransactionScope» с уровнем изоляции по умолчанию? – StriplingWarrior
@StriplingWarrior Предположим, что 'User A' и' User B' открывают форму, которая редактирует 'Object A'. Если 'User B' сохраняет и закрывает форму, форма пользователя 'A' теперь недействительна. Мне нужно иметь возможность предотвратить сохранение «User A», потому что они будут записывать записи, которые технически неверны. – test
Это обычная проблема, с которой обычно сталкивается * оптимистичный параллелизм *. EF полностью поддерживает эту стратегию параллелизма. –