Я являюсь частью команды, создающей веб-сайт на базе ADO.NET. Иногда у нас есть несколько разработчиков и инструмент автоматического тестирования, работающий одновременно с копией базы данных для разработки.
Мы используем уровень изоляции снимка, который, насколько мне известно, использует оптимистичный параллелизм: вместо блокировки он надеется на лучшее и выдает исключение, если вы пытаетесь зафиксировать транзакцию, если затронутые строки были изменены другой стороной во время перевод.
Чтобы использовать уровень изоляции моментальных снимков, мы используем:
ALTER DATABASE <database name>
SET ALLOW_SNAPSHOT_ISOLATION ON;
и в С#:
Transaction = SqlConnection.BeginTransaction(IsolationLevel.Snapshot);
Обратите внимание, что моментальный снимок IsolationLevel отличается от моментального снимка ReadCommitted, который мы также пробовали, но в настоящее время не используем.
Когда один из разработчиков входит в режим отладки и приостанавливает работу приложения .NET, он будет удерживать соединение с активной транзакцией во время отладки. Теперь я ожидаю, что это не будет проблемой - в конце концов, все транзакции используют уровень изоляции моментальных снимков, поэтому, пока одна транзакция приостановлена, другие транзакции должны иметь возможность нормально работать, поскольку приостановленная транзакция не удерживает никаких блокировок. Конечно, когда приостановленная транзакция завершится, скорее всего, будет обнаружен конфликт; но это приемлемо, пока другие разработчики и автоматизированные тесты могут работать беспрепятственно.
Однако на практике, когда один человек останавливает транзакцию во время отладки, все другие пользователи БД, пытающиеся получить доступ к тем же строкам, блокируются, несмотря на использование уровня изоляции моментальных снимков.
Кто-нибудь знает, почему это происходит и/или как я могу добиться настоящего оптимистичного (неблокирующего) параллелизма?
Решение (неудачное для меня): Remus Rusanu заметил, что писатели всегда блокируют других писателей; это поддерживается MSDN - он не совсем говорит об этом, а только упоминает, что нужно избегать блокировок чтения-записи. Короче говоря, поведение, которое я хочу, не реализовано в SQL Server.