基于值的条件锁定

本文关键字:锁定 条件 于值 | 更新日期: 2023-09-27 18:04:46

我正在编写一个允许用户在系统内创建作业的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
}

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

基于值的条件锁定

是的,您可以使用Dictionary<string, object>。链接一个lockObject到每个userId。

问题是要经常清理字典。

但是我想首先验证这里是否真的存在瓶颈。不要解决你没有的问题。

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

与其锁定每个方法,为什么不使用单例来管理User的权限呢?

它将负责提供剩余的配额,并在不丢失线程安全代码的情况下同时管理它们。

顺便说一下,一个名为CheckRemainingCreditsForUser的方法不应该删除允许,因为它的名字并没有暗示它,你可能是这个项目中唯一的开发人员,但是为了可重用性和代码理解,创建两个方法来管理它并没有坏处。

EDIT:这个对象还应该保存Users字典