ASP.NET MVC如何实现新增产品后1分钟内限制其他用户添加功能?
问题核心原因
你选用Session实现的思路本身就不符合需求逻辑:
ASP.NET MVC5的Session是单用户会话级存储,每个独立客户端(不同浏览器、不同设备、不同隐身窗口)的Session完全隔离,仅对当前发起请求的用户可见。你把操作者用户名存在当前用户的Session里,其他用户根本访问不到这个Session值,所以跨设备/跨浏览器访问时必然失效,哪怕你配置数据库持久化Session也解决不了这个逻辑问题。
正确实现方案
你需要使用全局共享存储来保存加锁状态,所有用户的请求都读取同一个存储里的锁信息,根据部署场景可选两种方案:
方案1:单服务器部署,用MemoryCache实现(最简单)
MemoryCache是服务器进程内的全局缓存,所有用户请求共享,自带过期时间配置,完全适配你的1分钟自动解锁需求。
实现代码:
首先引用命名空间System.Runtime.Caching,然后修改你的接口逻辑:
// 先定义全局缓存实例,也可以用依赖注入获取,这里做最简演示 private static readonly ObjectCache _globalCache = MemoryCache.Default; private const string AddProductLockKey = "Global_AddProduct_Lock_User"; public async Task<JsonResult> AddProducts(string citaId, string paciente, string medico, string modalidad) { var usuario = System.Web.HttpContext.Current.User.Identity.GetUserName(); // 先读取全局锁 var lockUser = _globalCache.Get(AddProductLockKey) as string; if (!string.IsNullOrEmpty(lockUser) && lockUser != usuario) { var objetoerrr1 = new { type = "error", message = $"you cannot add a product, WAIT 1 MIN." }; return Json(objetoerrr1, JsonRequestBehavior.AllowGet); } // ... 原有新增产品的业务代码 // 新增成功后写入全局锁,过期时间设为1分钟 CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(1) }; _globalCache.Set(AddProductLockKey, usuario, policy); // 原有返回逻辑 }
注意:如果需要允许操作人在1分钟内多次新增时自动续期,可以在
lockUser == usuario的分支里加一句刷新缓存过期时间的逻辑。
方案2:多服务器负载均衡部署
此时单服务器的内存缓存无法跨服务器共享,你可以二选一:
- 用分布式缓存(比如Redis)存储锁信息,逻辑和上面
MemoryCache的实现完全一致,只是把缓存操作换成Redis的读写接口即可 - 把锁信息存在业务数据库里,新增一张锁表,存锁的持有者、过期时间,每次请求先查数据库判断锁状态,定时或者每次查询的时候清理过期的锁记录即可。
内容的提问来源于stack exchange,提问作者EthernalHusky
相关产品推荐
相关产品推荐

