基于值的条件锁定

时间:2014-05-22 09:39:25

标签: c#

我正在编写一个允许用户在系统中创建作业的Web服务。每个用户都可以创建他们可以创建的作业数量。我有一个方法,检查用户是否有一些看起来像这样的剩余信用:

private bool CheckRemainingCreditsForUser(string userId)
{
    lock(lockObj)
    {
       var user = GetUserFromDB(userId);
       if (user.RemaingCredit == 0) return false;
       RemoveOneCreditFromUser(user);
       SaveUserToDB(user);
    }
}

我可以通过这种方法看到的问题是,如果多个不同的用户同时发出请求,他们将一次只能处理一个请求,这可能会导致客户端出现性能问题。是否可以做这样的事情?

private bool CheckRemainingCreditsForUser(string userId)
{
    //If there is a current lock on the value of userId then wait 
    //If not get a lock on the value of userId
    var user = GetUserFromDB(userId);
    if (user.RemaingCredit == 0) return false;
    RemoveOneCreditFromUser(user);
    SaveUserToDB(user);
    //Release lock on the value of userId
}

这意味着可以同时处理具有不同userIds的请求,但具有相同userId的请求必须等待先前的请求完成

2 个答案:

答案 0 :(得分:1)

是的,你可以用Dictionary<string, object>做到这一点。将lockObject链接到每个userId。

问题在于经常清理那个词典。

但我会首先确认这里确实存在瓶颈。不要解决你没有的问题。

另一种方法是在数据库中进行(乐观)并发检查,并处理(罕见)冲突情况。

答案 1 :(得分:0)

为什么不使用 Singleton 来管理用户的权利,而不是锁定每种方法?

它将负责提供剩余的配额并同时管理它们而不会丢失线程安全的代码。

顺便说一下,一个名为CheckRemainingCreditsForUser的方法不应该删除配额,因为这个名称并不意味着它,你可能是这个项目中唯一的开发人员,但是制作2个方法来管理它不会有什么坏处。可重用性和代码理解。

编辑:此对象还应包含用户字典