c# - 防止来自用户的并发控制器请求
问题描述
我的 ASP.Net MVC 项目中有一个控制器操作,不应允许同一用户同时执行该操作。当用户提交请求 #1 并且在请求 #1 仍在运行期间,所有其他请求都应被拒绝。这个逻辑必须基于用户。
我写了一些代码,我认为它可以工作
由于我在 localhost 上进行测试时遇到问题,并且它是我网站的一个敏感部分,如果您能查看代码并给我一些反馈,我将不胜感激!
更新
我将下面的代码发布到生产环境中,曾经有一次用户创建了一个锁但没有解锁的情况。我不知道问题出在哪里。
控制器
public class LockTestController : Controller
{
public string Submit(int userId)
{
try
{
if (TransactionLockRepository.HasLock(userId))
return DateTime.Now + $"Err: UserId {userId} already requested already ";
//todo: do important stuff an user should not execute concurrently
TransactionLockRepository.RemoveLock(userId);
return DateTime.Now + " Submit successfully. UserId: " + userId + " ";
}
catch (Exception e)
{
TransactionLockRepository.RemoveLock(userId);
Debug.WriteLine(e);
return DateTime.Now + " Error " + e;
}
}
}
锁库
public static class TransactionLockRepository
{
private static readonly ConcurrentBag<int> UserLocks = new ConcurrentBag<int>();
private static readonly object _lockInsert = new object();
private static readonly object _lockRemove = new object();
public static bool HasLock(int userId)
{
lock (_lockInsert)
{
var i = userId;
var hasLock = UserLocks.TryPeek(out i);
if (hasLock)
return true;
UserLocks.Add(userId);
return false;
}
}
public static bool RemoveLock(int userId)
{
lock (_lockRemove)
{
var i = userId;
UserLocks.TryTake(out i);
return i == userId;
}
}
}
我希望只有当 userId 在 Lock Repo 中时请求才会被阻止。其他用户不应受到影响
解决方案
我认为这不会一直有效。如果两个动作请求HasLock
同时调用方法怎么办?hasLock
并且这两个请求在执行代码行之前依次将变量设置为 false UserLocks.Add(userId);
。在这种情况下,您可能需要在 HasLock 方法中使用 lock :
private static object _lockObj = new object();
public static bool HasLock(int userId)
{
lock(_lockObj)
{
var i = userId;
var hasLock = UserLocks.TryPeek(out i);
if (hasLock)
return true;
UserLocks.Add(userId);
return false;
}
}
推荐阅读
- javascript - 带有jquery和jade的nodejs
- javascript - Javascript Date.getTime() 仅在 Internet Explorer 11 中返回 NaN
- node.js - 如何更新 Firestore 文档中字段对象的适当性?
- javascript - 循环元素并检查类是否存在 javascript
- google-sheets - 谷歌表,他们是一种使用垂直数据“迷你图”公式的方法吗?
- python - 在 Django 中区分用户
- php - Slim + PHP + MySQLi:异常:未定义标识符“select * from users”
- visual-studio-code - 在 Ubuntu 中编辑/查看文件时,将 Visual Studio Code 编辑器添加为 WinSCP 中的默认编辑器
- python - 如何在 odoo 10 中使用 xpath 属性?
- angularjs - 我想选择我的当按下包含它的 div 上的任意位置时