Мой сценарий распространен: у меня есть хранимая процедура, которой нужно обновить несколько таблиц. если одно из обновлений не удалось - нужно откатить все обновления. прямой ответ - включить все обновления в одну транзакцию и просто откатить ее. однако в системе, подобной нашей, это вызовет проблемы параллелизма. когда мы разбиваем обновления на несколько коротких транзакций - мы получаем пропускную способность ~ 30 одновременных выполнений в секунду, прежде чем начнут возникать проблемы с блокировкой. если мы поместим его в одну транзакцию, которая охватывает их все, мы получим параллельную ~ 2 в секунду, прежде чем появится взаимоблокировка.
в нашем случае мы размещаем блок try-catch после каждой короткой транзакции и вручную DELETE/Update обратно изменения из предыдущих. поэтому, по сути, мы имитируем поведение транзакции очень дорогим способом... Он работает нормально, поскольку он хорошо написан и не получает много "откатов"... одна вещь, которую этот подход вообще не может решить, - это случай тайм-аута команды из Интернета. сервер/клиент.
Я много читал во многих формах и блогах, просматривал MSDN и не нашел хорошего решения. многие представили проблему, но я еще не видел хорошего решения.
Вопрос в следующем: существует ли ЛЮБОЕ решение этой проблемы, которое позволит стабильно откатывать обновления для нескольких таблиц без необходимости устанавливать монопольную блокировку для всех строк на протяжении всей длительной транзакции.
Предположим, что это не проблема оптимизации. Вероятно, таблицы почти максимально оптимизированы и могут обеспечить очень высокую пропускную способность, пока не произойдет взаимоблокировка. нет блокировок таблиц/страниц и т. д. все блокировки строк при обновлениях, но когда у вас так много одновременных сеансов, некоторым из них необходимо обновить одну и ту же строку...
это может быть через SQL, C# на стороне клиента, C# на стороне сервера (расширить SQL-сервер?). Есть ли такое решение в какой-либо книге/блоге, которое я не нашел?
мы используем SQL Server 2008 R2, к которому подключается клиент/веб-сервер .NET. Пример кода:
Создать процедуру sptest Начать транзакцию Обновить таблицу1 Обновить таблицу2 Подтвердить транзакцию
В этом случае, если sptest запускается дважды, второй экземпляр не может обновить таблицу 1 до тех пор, пока экземпляр 1 не зафиксируется. По сравнению с этим
Создать sptest2 Обновить таблицу1 Обновить таблицу2
Sptest2 имеет гораздо более высокую пропускную способность, но есть вероятность повреждения данных. Это то, что мы пытаемся решить. Есть ли хотя бы теоретическое решение этой проблемы?
Спасибо, Дж.С.