Проблема транзакции Nhibernate - IsolationLevel.Serializable - PullRequest
1 голос
/ 28 марта 2011

У меня есть задача, которая занимает довольно много времени. Поэтому я бы хотел, чтобы несколько программ / потоков / компьютеров выполняли одну и ту же задачу, чтобы ускорить процесс. Каждое задание требует уникальных идентификаторов, которые хранятся в БД, поэтому я подумал, что эти идентификаторы могут быть получены следующим образом:

NHibernateSession.Current.BeginTransaction(IsolationLevel.Serializable);
list = NHibernateSession.Current.CreateCriteria<RelevantId>().SetFirstResult(0).SetMaxResults(500).List<RelevantId>();

foreach (RelevantId x in list)
{
RelevantIdsRepository.Delete(x);
}
NHibernateSession.Current.Transaction.Commit();

К сожалению, через некоторое время возникает исключение, если к базе данных обращается несколько процессов (количество удаленных объектов не совпадает с размером пакета). Почему это? Уровень изоляции БД должен быть в порядке, не так ли? Спасибо.

С наилучшими пожеланиями,

Christian

Ответы [ 2 ]

0 голосов
/ 28 марта 2011

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

Это не работает так, как вы его реализовали.Все процессы читают одинаковые идентификаторы.После совершения транзакции они исчезают из базы данных.До тех пор они видны всем.Уровень изоляции гарантирует, что другие транзакции не смогут прочитать их после удаления.Но до тех пор они все могут их читать.

Распределить нагрузку не так просто.Вы можете

  • поддерживать идентификаторы в таблице, где каждый процесс регистрирует себя в качестве исполнителя и фиксирует его перед запуском (обработка конфликтов, например, StaleObjectStateException).Обязательно очищайте его даже в случае сбоя процесса.
  • напишите центральную службу, которая распространяет идентификаторы.
0 голосов
/ 28 марта 2011

Проблема в том, что он работает медленно, возможно, из-за того, что вы выполняете несколько операторов SQL в цикле. Вы должны увидеть, если невозможно удалить все сущности в одном пакетном операторе.

...