ConcurrencyException'ы замедляют работу в 20 раз. Что делать?
От: Аноним  
Дата: 02.12.13 14:43
Оценка:
Есть простой процесс:

1. Снять с №1 счета X.
2. Увеличить №2 счет на X.
3. Записать текущие остатки на счетах №1 и №2.

Проблема в том, что счет №1 системный и на него зачисляют/снимают по множеству раз в секунду. Если использовать оптимистическую блокировку в Entity Framework, то при SaveChanges() постоянно вываливается DbUpdateConcurrencyException (так как кто-то другой успел изменить раньше нас). После DbUpdateConcurrencyException, конечно, перезапускаем вставку и в конечном счете все проходит, однако эти перезапуски приводят к падению скорости в 20 раз (!) даже по сравнению с обычной блокировкой (lock) и записью в один поток.

И исполнение данных в транзакции не решает проблему: ни один вид транзакций (SERIALIZABLE, REPEATABLE READ, READ COMMITTED) не запрещает читать то что мы прочитали или изменять то что мы уже изменили (но еще не читали). То есть опять таки будет множество перезпусков транзакций, которые приведут к лишней работе и потере производительности.

Что делать? Есть ли что лучшее, чем использование ручной блокировки "EXEC sp_getapplock" и исполнения в одном потоке?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.