我有一个使用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
两个线程尝试对同一个东西进行操作,从而导致混乱。
我错过了什么吗?谢谢。
编辑:更改代码以反映实际版本中的日志记录方式。