Entity Framework 数据并发访问错误原因分析与系统架构优化
本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍
1. 发现问题
系统新模块上线后,使用频率较高,故在实际使用和后期的问题重现测试中,产生了一下系列的数据访问错误
错误是比较常见的错误
2. 分析问题
系统的架构为前端、业务层与数据层三层架构,采用Entity Framework 3.5作为数据处理技术,采用shared context per request模式,参照的是codeplex上的一个示例。示例地址(此文通俗易懂,代码结构也很清晰,个人很喜欢)
Entity模式的代码如下:
- public partial class SPMIPEntities
- {
- public static SPMIPEntities Context
- {
- get
- {
- string objectContextKey = "MIP_" + HttpContext.Current.GetHashCode().ToString("x");
- if (!HttpContext.Current.Items.Contains(objectContextKey))
- {
- HttpContext.Current.Items.Add(objectContextKey, new SPMIPEntities());
- }
- return HttpContext.Current.Items[objectContextKey] as SPMIPEntities;
- }
- }
- }
基于以上,根据系统的报错位置研究Entity实例并发与共享的问题,搜索了一些entity framework相关的资料。此问题主要从两个角度去着手解决:缩短Entity实例的存在时间和降低Entity实例的共享性,并考虑性能,因为Entity需要手动Dispose。
首先添加手动Dispose逻辑,我们的项目为SharePoint应用程序,所以和一般的.net略有不同。自行开发了一个BasePage类,所有的应用程序页面都继承自该类,BasePage类又继承自LayoutsPageBase类,要做到使用完Entity后及时Dispose,最好也写在页面的类似结束请求的事件里,于是在后台敲上protected空格override空格D->发现可重写Dispose方法,大喜,代码如下:
- public override void Dispose()
- {
- string objectContextKey = "MIP_" + HttpContext.Current.GetHashCode().ToString("x");
- if (HttpContext.Current.Items.Contains(objectContextKey))
- {
- SPMIPEntities ctx = HttpContext.Current.Items[objectContextKey] as SPMIPEntities;
- if (ctx != null)
- {
- ctx.Dispose();
- HttpContext.Current.Items.Remove(objectContextKey);
- }
- }
- base.Dispose();
- }
修改之后部署,测试,发现报错了:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection
没理由会这样,因为每个请求都会实例化新的Entity,不可能会被提前释放。
调试代码,断点卡到第一段代码get下面。重启服务,访问系统,附加进程开始调试,第一次get进来了,new了一个Entity实例出去,页面加载了出来;刷新页面,发现没有再次中断,到这里,就非常的不合理了,肯定有忽视掉的地方,于是回过头来一层一层查看代码,发现业务层和数据层的类都被写成了单例模式,举例如下
- public class DAC
- {
- #region 变量
- // 本类对象
- private static DAC _newNewInstance;
- private SPMIPEntities ctx = null;
- #endregion
- #region 构造函数
- /// <summary>
- /// 私有构造函数
- /// </summary>
- private DAC()
- {
- ctx = SPMIPEntities.Context;
- }
- #endregion
- #region 公有方法
- /// <summary>
- /// 本类实例对象
- /// </summary>
- /// <returns>
- /// 返回DAC对象
- /// </returns>
- public static DAC GetNewInstance()
- {
- if (_newNewInstance == null)
- {
- _newNewInstance = new DAC();
- }
- return _newNewInstance;
- }
- }
问题一定就在这里了,将单例模式改掉,修改为如下结构
- public class DAC
- {
- private SPMIPEntities ctx = null;
- private DAC()
- {
- ctx = SPMIPEntities.Context;
- }
- public static DAC GetNewInstance()
- {
- return new DAC();
- }
- }
修改完后部署重复上述步骤调试,预期中的结果。
下周再和团队一起系统地测试一遍,看看是不是有效果。
本来预期中的架构是没什么问题的,谁知当时又将操作类做成了单例模式而没有引起重视,为当前错误的爆发埋下了伏笔。架构还是应该多推敲,多考虑的。
要下班了,所以写的有些仓促;写得看起来很简单,但是研究的过程并不是特别简单,都是耗费时间的。特此记录。
转载于:https://www.cnblogs.com/lenther2002/p/4814944.html
Entity Framework 数据并发访问错误原因分析与系统架构优化相关推荐
- Property 'X' not found on type entity.Customer错误原因分析
错误原因分析: 实体类 entity.Customer的属性x一定要小写,规范规定 属性值的首字母必须小写. 另外需要在映射表上把小写字母属性值x 映射到数据库的表里的值大写X
- mysql数据表数据丢失6_MYSQL数据表损坏的原因分析和修复方法小结
MYSQL数据表损坏的原因分析和修复方法小结 1.表损坏的原因分析 以下原因是导致mysql 表毁坏的常见原因: 1. 服务器突然断电导致数据文件损坏. 2. 强制关机,没有先关闭mysql 服务. ...
- 段错误原因分析和查找
转自:http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之 ...
- Lua(Codea) 中 table.insert 越界错误原因分析
2019独角兽企业重金招聘Python工程师标准>>> Lua(Codea) 中 table.insert(touches, touch.id, touch) 越界错误原因分析 背景 ...
- “undefined reference to JNI_GetCreatedJavaVM”和“File format not recognized”错误原因分析...
"undefined reference to JNI_GetCreatedJavaVM"和"File format not recognized"错误原因分析 ...
- entity framework 删除数据库出现错误的解决方法--最土但是很有效的方法
entity framework 删除数据库出现错误的解决方法--最土但是很有效的方法 参考文章: (1)entity framework 删除数据库出现错误的解决方法--最土但是很有效的方法 (2) ...
- 阿里云存储表格存储TableStore-高并发IM系统架构优化实践
文章地址:https://yq.aliyun.com/articles/66461?utm_campaign=66461&utm_medium=images&utm_source=os ...
- mysql 表损坏_MYSQL数据表损坏的原因分析和修复方法小结(推荐)
1.表损坏的原因分析以下原因是导致mysql 表毁坏的常见原因: 1. 服务器突然断电导致数据文件损坏. 2. 强制关机,没有先关闭mysql 服务. 3. mysqld 进程在写表时被杀掉. 4. ...
- mysql 1597_MYSQL数据表损坏的原因分析和修复方法
1. 表损坏的原因分析 以下原因是导致mysql 表毁坏的常见原因: 1. 服务器突然断电导致数据文件损坏. 2. 强制关机,没有先关闭mysql 服务. 3. mysqld 进程在写表时 ...
最新文章
- WPF中的动画——(二)From/To/By 动画
- 清北学堂模拟赛d5t4 套路
- Python基础训练题-简单数学公式
- 【测试】物料帐单/多级差异流转测试
- 关于日志的常用配置(log4j和logback)
- 行业精英聚首谈智慧营销:团队打造、管理策略、权力分配、成功因素、IT 治理……...
- 唯有自己变得强大_物竞天择,适者生存,唯有强大自己,方能百毒不侵
- Mr.J-- HTTP学习笔记(七)-- 缓存
- 【机器学习】监督学习--(分类)逻辑回归
- 添加文字 高德地图_教您,如何在高德和腾讯定位自己的店铺位置
- java map 内存分配_mapreduce 内存分配
- 高质量程序设计指南:C++/C语言
- 文档转换 云服务器,pdf转换成word云服务器
- 激战和ErgoDex DX1
- C51数字钟程序-ZT(拿来学习用)
- flutter 显示表情
- arp毒化攻击 使用kali下ettercap工具查看其他人浏览图片信息实验
- 基于ATmega16单片机和GPS的多用途定位仪设计
- 性能测试——响应时间
- 一个测人的眼力的贴子!
热门文章
- latex设置一级标题样式不居中_Word应用“样式”的设置
- 从前端view到数据访问逻辑的思维导图
- stm32时钟树_STM32中的时钟
- mysql long类型_BAT架构师46面试题:spring+多线程+Redis+MySQL(建议收藏)
- wordpress 调用css,WordPress调用CSS最常用的方法有哪些?
- 橱柜高度与身高对照表_厨房台面高度是多少 厨房台面如何选购
- 北京小学 计算机派位,北京小升初电脑派位原理详解!和对口直升入学有什么区别?...
- php drive mssql,wamp下对MS SQLSERVER的连接配置,PHP+THINKPHP5通过
- char* 去除后面几个字符_【算法打卡】去除重复字母
- 云服务器一般选什么系统,云服务器一般选择什么系统好