Вы лаете не на то дерево.
Deadlock означает, что вся область транзакции отменена. В зависимости от вашего приложения, вы можете перезапустить с блока using
, т.е. новый TransactionScope, но это вряд ли будет правильным. Причина, по которой вы видите тупик, заключается в том, что кто-то другой изменил данные, которые вы тоже меняли. Поскольку большинство из этих обновлений применяют обновление к значению, ранее считанному из базы данных, тупик является четким признаком того, что все прочитанное вами было изменено . Поэтому повторное применение ваших обновлений без чтения приведет к перезаписи всего, что было изменено другой транзакцией, что приведет к потере обновлений. Вот почему тупиковая блокировка почти никогда не может быть «автоматически» повторена, новые данные должны быть повторно загружены из БД, если было задействовано действие пользователя (например, редактирование формы), то пользователь должен быть уведомлен и должен повторно подтвердить изменения, и только тогда обновление можно попробовать снова. Только определенные типы действий автоматической обработки могут быть отменены, но они никогда не повторяются, как в «попытаться написать снова», но они всегда действуют в цикле «чтение-обновление-запись», и взаимоблокировки заставят цикл повторить попытку, и так как они всегда начинаются с «читать». Они автоматически самокорректируются.
При этом ваш код блокируется, скорее всего, из-за злоупотребления уровнем изоляции сериализации, когда в этом нет необходимости: с использованием нового TransactionScope () считается вредным . Вы должны перезаписать параметры транзакции, чтобы использовать уровень изоляции ReadCommitted, сериализуемый почти никогда не требуется и является гарантированным способом достижения взаимоблокировок.
Второй вопрос - Почему блокирует сериализацию? Он блокируется из-за сканирования таблиц, которые указывают, что у вас нет надлежащих индексов для чтения и обновлений.
Последняя проблема заключается в том, что вы используете RequiresNew
, что опять-таки в 99% случаев неверно. Если у вас нет реального глубокого понимания того, что происходит, и пуленепробиваемого обоснования необходимости отдельной транзакции, вы всегда должны использовать Required
и подключиться к включающей транзакции звонящего.