【发布时间】:2012-02-13 22:58:07
【问题描述】:
您将如何使用以下代码解决并发问题?在此示例中,我们想知道为什么用户身份验证失败。问题是这段代码对数据库进行了两次单独的调用,但我们希望整个方法发生在概念事务中。具体来说,我们对isolation 感兴趣。在我们确定身份验证失败的原因之前,我们不希望在执行此方法期间的并发写入影响我们的读取。
我想到了几个解决方案:Thread Locking、TransactionScope 和 Optimistic Locking。我真的很喜欢乐观锁定的想法,因为我认为冲突可能很少见,但是 .NET 中没有内置的东西可以做到这一点,对吧?
另外 - 在这种情况下,这真的值得关注吗?什么时候考虑这样的并发问题很重要,什么时候不重要?在实施解决方案时需要考虑什么?表现?锁定的持续时间?发生冲突的可能性有多大?
编辑:在查看了 Aristos 的回答后,我认为我真正想要的是 Authenticate 方法的某种“snapshot”隔离级别。
public MembershipStatus Authenticate(string username, string password)
{
MembershipUser user = Membership.GetUser(username);
if (user == null)
{
// user did not exist as of Membership.GetUser
return MembershipStatus.InvalidUsername;
}
if (user.IsLockedOut)
{
// user was locked out as of Membership.GetUser
return MembershipStatus.AccountLockedOut;
}
if (Membership.ValidateUser(username, password))
{
// user was valid as of Membership.ValidateUser
return MembershipStatus.Valid;
}
// user was not valid as of Membership.ValidateUser BUT we don't really
// know why because we don't have ISOLATION. The user's status may have changed
// between the call to Membership.GetUser and Membership.ValidateUser.
return MembershipStatus.InvalidPassword;
}
【问题讨论】:
-
我不确定您是否真的需要担心这里的隔离问题。在调用
GetUser和ValidateUser之间,用户被删除或锁定的可能性有多大?更重要的是,您不应该将这些信息暴露给用户。如果您针对“密码错误”、“用户不存在”和“帐户被锁定”显示不同的消息,则试图入侵您网站的人可能会利用该信息获取有效用户名列表。您不希望这样,因为这些用户名可能有助于利用您的基础架构中的其他漏洞。 -
+1 表示响应。我可能在这里使用了一个糟糕的例子(尽管我计划区分“无效凭据”和“帐户被锁定”,也许我需要重新考虑)。我只是不喜欢数据可以在我下面改变的事实!并发难!如果我需要数据保持一致怎么办,您有什么建议?
标签: c# asp.net database concurrency sqlmembershipprovider