У меня есть приложение S # arp Architecture, в котором реализована облегченная функция обработки очередей, благодаря которой различные потоки извлекают объекты из списка и устанавливают свой статус, чтобы отметить факт начала обработки этих элементов.
Несмотря наОборачивая бит начальной обработки в явные транзакции и используя блокировку C # (), я все еще иногда запускаю их одновременно.
Не жалею ли я, что не использовал 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
.. и затем оба потока пытаются работать с одним и тем же и создают беспорядок.
Чего мне не хватает?Спасибо.
edit: изменен код, чтобы отразить, как работает логирование в реальной версии