我有一个 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
.. 然后两个线程都尝试对同一事物进行操作并造成困惑。
我错过了什么?谢谢。
编辑:更改代码以反射(reflect)我的日志记录在真实版本中的工作方式
最佳答案
在您的 NHibernate 映射中设置并发,这篇文章应该可以帮助您入门。
关于c# - NHibernate并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6100444/