多用户并发保存事务时用户ID存入数据库为空问题咨询
问题根因分析
- 空catch块吞掉所有错误:你写的catch逻辑内没有任何日志和异常处理,只要获取用户信息的任意步骤报错都会直接终止执行,最终UserID没有赋值自然为默认空值,并发场景下的数据库连接波动、存储过程执行超时、参数非法都会触发这个问题,你完全感知不到错误发生。
- WebMethod默认不支持Session:你在WebMethod中调用构造函数,但默认WebMethod是关闭Session访问权限的,直接取
HttpContext.Current.Session.SessionID要么是空值要么是错误的无效ID,自然查不到对应用户。 - UrlReferrer空引用风险:
HttpContext.Current.Request.UrlReferrer在用户直接访问页面、浏览器禁用来路统计、HTTPS跳转HTTP场景下会返回null,直接取.Authority属性会抛空引用异常,被空catch吞掉后直接终止用户信息获取逻辑。 - Dns反向解析高失败率:用公网IP做反向解析大概率会超时或者解析失败,这一步抛异常也会被catch直接吞掉,导致用户信息获取中断。
- 存储过程并发查询问题:如果你的
PACKCOMMON.GETLOGGEDUSERID存储过程没有加正确的过滤条件和行锁,多用户并发查询时很容易出现交叉匹配,取不到当前请求对应用户的ID。
修复方案
- 首先补全catch块的日志逻辑,先定位具体报错点,也可以直接抛出异常避免后续用空UserID存库:
catch (Exception ex) { clsErrorLogEntity.fn_AddNewErrorLog(DateTime.Now, "clsLoggedUser.cs 构造函数执行失败", ex.Message, ex); // 新增抛错逻辑,避免后续逻辑用空用户ID执行 throw new InvalidOperationException("获取当前登录用户信息失败", ex); }
- 给用到Session的WebMethod加上Session启用特性:
[WebMethod(EnableSession = true)] public string 你的保存事务方法名() { // 原有业务逻辑 }
- 修复UrlReferrer空引用问题,增加空判断:
string strUrl = HttpContext.Current.Request.UrlReferrer?.Authority ?? "";
- 移除不必要的Dns反向解析逻辑,该逻辑性能差且失败率极高,直接用
REMOTE_ADDR参数存客户端IP即可,确实需要主机名可以由前端传参。 - 优化
PACKCOMMON.GETLOGGEDUSERID存储过程,确保SessionID、系统名称、URL三个参数同时匹配才返回用户ID,并发查询时加读锁避免脏读。 - 使用用户信息前先判断登录状态,避免用空值存库:
clsLoggedUser objclsLoggedUser = new clsLoggedUser(); if(!objclsLoggedUser.IsLoggedIn) { // 抛出未登录异常,终止后续保存操作 throw new UnauthorizedAccessException("用户未登录,无法执行保存操作"); } // 再正常使用UserID、UserName等属性
内容的提问来源于stack exchange,提问作者Mridul V
相关产品推荐
相关产品推荐

