我们有一个长期运行的用户操作,由工作进程池处理。数据输入和输出来自 Azure SQL。
主 Azure SQL 表结构列近似为
[UserId, col1, col2, ... , col N, beingProcessed, lastTimeProcessed ]
beingProcessed
是布尔值并且lastTimeProcessed
是日期时间。每个工人角色的逻辑如下所示,并且有多个工人处理(每个工人都有自己的实体框架层),本质上beingProcessed
是用于互斥目的的锁
问题:如何beingProcessed
根据上述负载处理“锁”本身的并发问题?我认为 read-modify-write
对beingProcessed
需求的操作必须是原子的,但我对其他策略持开放态度。也对其他代码改进开放。
[更新]:我想知道TransactionScope
这里是否需要... http://msdn.microsoft.com/en-US/library/system.transactions.transactionscope(v=vs.110).aspx
代码:
public void WorkerRoleMain()
{
while(true)
{
try
{
dbContext db = new dbContext();
// Read
foreach (UserProfile user in db.UserProfile
.Where(u => DateTime.UtcNow.Subtract(u.lastTimeProcessed)
> TimeSpan.FromHours(24) &
u.beingProcessed == false))
{
user.beingProcessed = true; // Modify
db.SaveChanges(); // Write
// Do some long drawn processing here
...
...
...
user.lastTimeProcessed = DateTime.UtcNow;
user.beingProcessed = false;
db.SaveChanges();
}
}
catch(Exception ex)
{
LogException(ex);
Sleep(TimeSpan.FromMinutes(5));
}
} // while ()
}