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

У меня есть приложение S#arp Architecture, которое реализует облегченную функцию обработки очередей, при которой различные потоки извлекают объекты из списка и устанавливают свой статус, чтобы отметить тот факт, что обработка этих элементов началась.

Несмотря на оборачивание бита обработки запуска в явных транзакциях и использование C# lock(), я все равно иногда получаю их запуск одновременно.

Жалею ли я о том, что не использую MSMQ ... да, но теперь это параллельное поведение сбило меня с толку. Очевидно, есть кое-что, чего я не понимаю в транзакциях и очистке NHibernate. Можете ли вы помочь мне?

Вот соответствующие биты кода:

private static object m_lock = new object();

private bool AbleToStartProcessing(int thingId)
{
    bool able = false;
    try
    {
        lock (m_lock)
        {
            this.thingRepository.DbContext.BeginTransaction();
            var thing = this.thingRepository.Get(thingId);
            if (thing.Status == ThingStatusEnum.PreProcessing)
            {
                able = true;
                thing.Status = ThingStatusEnum.Processing;
            }
            else
            {
                logger.DebugFormat("Not able to start processing {0} because status is {1}",
                        thingId, thing.Status.ToString());
            }
            this.thingRepository.DbContext.CommitTransaction();
        }
    }
    catch (Exception ex)
    {
        this.thingRepository.DbContext.RollbackTransaction();
        throw ex;
    }
    if (able)
        logger.DebugFormat("Starting processing of {0}",
                        thingId);
    return able;
}

Я ожидал, что это гарантирует, что только один поток может изменить состояние "вещи" за один раз, но я получаю это в своих журналах довольно регулярно:

2011-05-18 18:41:23,557 thread41 DEBUG src:MyApp.Blah.ThingJob - Starting processing of 78090
2011-05-18 18:41:23,557 thread51 DEBUG src:MyApp.Blah.ThingJob - Starting processing of 78090

... а затем оба потока пытаются работать с одним и тем же и создают беспорядок.

Что мне не хватает? Благодарю.

изменить: изменил код, чтобы отразить, как моя регистрация работает в реальной версии

2 ответа

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

http://ayende.com/blog/3946/nhibernate-mapping-concurrency

Я думаю, что вы только что получили статус, который вы используете, чтобы установить, что вы обрабатываете, и чтобы проверить, что вы уже обрабатываете. первый в наборе ThingStatusEnum.Processing, но следующий парень проверяет что-то другое - ThingStatusEnum.PreProcessing. потому что ThingStatusEnum.Processing!= ThingStatusEnum.PreProcessing, ваша блокировка означает, что два потока не являются

Другие вопросы по тегам