Проблемы параллелизма - PullRequest
       20

Проблемы параллелизма

0 голосов
/ 12 февраля 2010

Вот моя ситуация (SQL Server):

У меня есть веб-приложение, которое использует nHibernate для доступа к данным, и еще 3 настольных приложения. Все имеют доступ к одной и той же базе данных и могут использовать одни и те же таблицы одновременно.

Теперь, с помощью NH, я пакетирую выборки, чтобы загрузить агрегат со всей его иерархией - так что я бы увидел, что от 4 до 7 выборок выдаются одновременно (не уверен, имеет ли это значение).

Каждые несколько дней одно из приложений будет получать сообщение: «Транзакция выбрана жертвой тупика». (это обычно появляется на выбор)

Я попытался перейти на изоляцию моментальных снимков в базе данных, но это не помогло - в итоге я получил:

Транзакция изоляции моментального снимка прервана из-за конфликта обновлений. Вы не можете использовать изоляция моментального снимка для доступа к таблице «...» прямо или косвенно в база данных "..." для обновления, удалить или вставить строку, которая имеет был изменен или удален другим сделка. Повторите транзакцию или изменить уровень изоляции для обновить / удалить оператор.

Какие у вас есть предложения для этой ситуации? Что я должен попробовать или что я должен прочитать, чтобы найти решение?

EDIT:

На самом деле там нет рейдов :). Количество пользователей в день небольшое (я скажу 100 в день - с сотнями небольших заказов в напряженный день), база данных немного больше - около 2 ГБ и растет быстрее с каждым днем.

Это бизнес-приложение, которое обрабатывает заказы, электронные письма, отчеты, счета и тому подобное.

Ленивая загрузка в этом случае не подходит.

Полагаю, лучше всего внимательно посмотреть на эти индексы.

Ответы [ 3 ]

1 голос
/ 12 февраля 2010

тупики сложны. Взаимная блокировка означает, что по крайней мере два сеанса имеют блокировки и ожидают друг друга, чтобы снять другую блокировку; поскольку оба ожидают, блокировки никогда не снимаются, ни один сеанс не может продолжаться, и возникает тупик.

Другими словами, A имеет блокировку X, B имеет блокировку Y, теперь A хочет Y и B хочет X. Ни один из них не откажется от блокировки, которую они имеют, пока они не закончат свою транзакцию. Оба будут ждать бесконечно, пока не получат другой замок. SQL Server видит, что это происходит, и убивает одну из транзакций, чтобы предотвратить взаимоблокировку. Вам не поможет изоляция моментальных снимков - БД все еще должна сохранять атомарность транзакций.

Никто не может дать простой ответ о том, почему возникла тупиковая ситуация. Вам нужно будет профилировать свою заявку, чтобы узнать.

Начните здесь: Как отлаживать тупики SQL . Это хорошее вступление.

Далее посмотрите на Обнаружение и устранение тупиков в MSDN. Это даст вам много полезной информации о причинах возникновения взаимоблокировок и поможет понять, на что вы обращаете внимание.

Есть также несколько предыдущих вопросов SO, на которые вы, возможно, захотите посмотреть:

Или, если взаимные блокировки встречаются очень редко, просто напишите в свое приложение код обработки исключений, чтобы повторить транзакцию в случае возникновения взаимоблокировки. Иногда бывает очень трудно (если не почти невозможно) предотвратить определенные тупики. Пока вы пишете транзакционно-безопасный код, это не конец света; Совершенно безопасно просто повторить транзакцию.

1 голос
/ 12 февраля 2010

Правильно ли настроено ваше оборудование (в частности, конфигурация RAID)? Способен ли он соответствовать вашей рабочей нагрузке?

Если аппаратное обеспечение работает хорошо и гудит, вы должны убедиться, что у вас есть «правильные» индексы, соответствующие рабочей нагрузке вашего запроса.

Многие проблемы блокировки / взаимоблокировки могут быть устранены с помощью правильных индексов (закрывающие индексы могут снять давление с кластеризованного индекса во время вставок).

Кстати: включение изоляции моментальных снимков увеличит давление на tempDB . Как настроен tempDB? RAID 0 предпочтителен (и даже лучше использовать SSD, если tempDB является узким местом).

0 голосов
/ 12 февраля 2010

Хотя такую ​​ошибку часто встречают в сеансах NHibernate с большим количеством пользователей, в вашем случае это происходит слишком часто.

Возможно, ваши объекты очень большие, что приводит к длительным выборам? И если ваш выбор занимает слишком много времени, это может указывать на проблемы с вашими индексами (как объясняет Митч Уит)

Если все в порядке, вы также можете попробовать Ленивая загрузка , чтобы отложить ваш выбор до тех пор, пока вам действительно не понадобятся ваши данные. Это может не подходить для вашей конкретной ситуации, поэтому вам нужно посмотреть, работает ли она.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...