基于值的条件锁定
本文关键字:锁定 条件 于值 | 更新日期: 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字典