- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 web 应用程序中存在 nhibernate 竞争条件问题。
我知道在使用旧版本的 log4net 时会发生这种情况(应该在 1.2.10 中修复),尽管我也经历过这种情况。因此,我们暂时禁用了 log4net,因为竞争条件会导致 IIS 崩溃,并且在生产中发生这种情况是 Not Acceptable 。加载实体时会发生这种情况(请参阅下面的堆栈跟踪)。除此之外,RavenDB中似乎也出现了类似的问题,参见这个link ,以及此处没有 NHibernate 的示例 link .
堆栈跟踪:
Server Error in '/' Application.
Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.IndexOutOfRangeException: Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.
Source Error:
Line 105:
Line 106: if(webUser.Id > 0) { // logged in
Line 107: _user = session.Get<User>(webUser.Id);
Line 108: if(_user == null) { // session exists, but no user in DB with this id
Line 109: new SessionInit().Remove();
Source File: \App_Code\SessionInit.cs Line: 107
Stack Trace:
[IndexOutOfRangeException: Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.]
System.Buffer.InternalBlockCopy(Array src, Int32 srcOffsetBytes, Array dst, Int32 dstOffsetBytes, Int32 byteCount) +0
System.IO.StreamWriter.Write(Char[] buffer, Int32 index, Int32 count) +117
System.IO.TextWriter.WriteLine(String value) +204
System.IO.SyncTextWriter.WriteLine(String value) +63
NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd) +71
NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session) +580
NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +275
NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +205
NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) +590
[GenericADOException: could not load an entity: [app.Presentation.User#338][SQL: SELECT user0_.userID as userID24_0_, user0_.instituteID as institut2_24_0_, user0_.email as email24_0_, user0_.password as password24_0_, user0_.username as username24_0_, user0_.mod_remarks as mod6_24_0_, user0_.lastLogin as lastLogin24_0_, user0_.active as active24_0_, user0_.isAcademic as isAcademic24_0_, user0_.created as created24_0_, (select p.firstName from ej_profile p where p.userID = user0_.userID) as formula11_0_, (select p.lastName from ej_profile p where p.userID = user0_.userID) as formula12_0_, (select p.timeZone from ej_profile p where p.userID = user0_.userID) as formula13_0_ FROM ej_user user0_ WHERE user0_.userID=?]]
NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister) +960
NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId) +76
NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session) +32
NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) +173
NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options) +181
NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType) +1019
NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType) +403
NHibernate.Impl.SessionImpl.Get(String entityName, Object id) +469
NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id) +374
NHibernate.Impl.SessionImpl.Get(Object id) +391
SessionInit.GetCurrentUser(ISession session) in j:\dev\app\app_wwwroot\App_Code\SessionInit.cs:107
DynamicPage.OnPreInit(EventArgs e) in j:\dev\app\app_wwwroot\App_Code\DynamicPage.cs:24
MemberPage.OnPreInit(EventArgs e) in j:\dev\app\app_wwwroot\App_Code\MemberPage.cs:20
members_stocks_Default.OnPreInit(EventArgs e) in j:\dev\app\app_wwwroot\members\Default.aspx.cs:28
System.Web.UI.Page.PerformPreInit() +49
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1716
用户的映射:
public class UserViewMapping : ClassMap<User>
{
public UserViewMapping() {
Table("ej_user");
Id(s => s.Id, "userID").GeneratedBy.Native();
Map(s => s.InstituteId, "instituteID");
Map(s => s.Email, "email");
Map(s => s.Password, "password");
Map(s => s.Name, "username");
Map(s => s.ModRemarks, "mod_remarks");
Map(s => s.LastLogin, "lastLogin");
Map(s => s.Active, "active");
Map(s => s.IsAcademic, "isAcademic");
Map(s => s.Created, "created");
Map(s => s.FirstName).Formula("(select p.firstName from ej_profile p where p.userID = userID)");
Map(s => s.LastName).Formula("(select p.lastName from ej_profile p where p.userID = userID)");
Map(s => s.TimeZone).Formula("(select p.timeZone from ej_profile p where p.userID = userID)");
HasMany<ProfileViewModel>(s => s.Profiles)
.Table("ej_profile")
.KeyColumn("userID")
.Cascade.All()
.Inverse();
}
一些细节:我使用两个 session 来进行查询和命令(以及两个 session 工厂),因为我使用了有点类似于 CQRS 的模式。一个 session 用于读取对象,一个 session 用于进行更改(这有助于我保持域模型简单,并查看模型和映射可能与命令模型不同)。
在我的开发环境(单用户)中加载用户 View 模型时发生竞争条件,但我们确保在生产中永远不会发生这种情况,因为它使 IIS 7 崩溃。此外,在生产中会有多个用户,所以也许该错误可能会更频繁地发生。
此外,我们还有很多使用 System.Data 和 MySql.Data.MySqlClient.MySqlDataAdapter 来读取/写入数据库的遗留代码。这能有影响吗?
我正在使用 NHibernate 3.1.0(将升级到 3.3.1GA,但这很难重现),并使用 fluenceNhibernate 进行映射。
sessionfactories 在 global.asax 中创建:
void Application_Start(object sender, EventArgs e)
{
QuerySessionFactory.Create(connectionString);
CommandSessionManager.Initialize(connString);
}
我的页面继承自打开和关闭查询 session 的 DynamicPage:
public class DynamicPage : System.Web.UI.Page
{
protected override void OnPreInit(EventArgs e)
{
Session = QuerySessionFactory.Instance.OpenSession();
}
protected override void OnUnload(EventArgs e) {
base.OnUnload(e);
Session.Close();
}
}
在 SessionInit 中(从 httpcontext.session 读取 userID,并创建一个“webuser”,一个具有一些简单信息(如 userId)的用户)。后来我把锁放在了一边,并在事务中完成了用户获取请求,不确定是否有用。
public IUser GetCurrentUser(ISession session) {
if(_user == null) {
var webUser = new SessionInit().Get;
if(webUser.Id > 0) { // logged in
lock(_lock) {
using(var tx = session.BeginTransaction()) {
_user = session.Get<User>(webUser.Id);
tx.Commit();
}
}
if(_user == null) { // session exists, but no user in DB with this id
new SessionInit().Remove();
}
((User)_user)._currentUser = webUser;
} else {
if(webUser is CurrentUser && webUser.Id == 0) {
if(HttpContext.Current.Session != null) {
HttpContext.Current.Response.Cookies.Remove("ASPSESSID");
HttpContext.Current.Request.Cookies.Remove("ASPSESSID");
HttpContext.Current.Session.RemoveAll();
HttpContext.Current.Session.Abandon();
}
if(HttpContext.Current.Request.Url.Host.Contains("members"))
HttpContext.Current.Response.Redirect("/login");
} else
if(webUser.Id == 0) {
var userId = webUser.Id;
var userName = webUser.UserName;
var loginUrl = webUser.LoginUrl;
var clientIp = webUser.ClientIp;
var isAdmin = webUser.IsAdmin();
return new eLab.Presentation.Visitor(userId, userName, loginUrl, clientIp, isAdmin, webUser.Theme);
}
}
if (_user == null)
return new eLab.Presentation.Visitor(webUser.Id, webUser.UserName, webUser.LoginUrl, webUser.ClientIp, false, webUser.Theme);
}
return _user;
}
命令 session 在需要时在 using block 中打开和关闭。
根据堆栈跟踪,问题发生在 StreamWriter -> System.Buffer 中,它再次被 System.IO.SyncTextWriter 调用,而 System.IO.SyncTextWriter 应该是 System.IO.TextWriter 周围的线程安全包装器。
由于这种情况发生在 TextWriter 中,有没有办法解决这个问题,使用线程安全的 TextWriter?
按照我在 DynamicPage 中的方式打开和关闭 session 是否安全?
由于这显然很难重现,因此也欢迎任何有关如何做到这一点的想法。
[更新]NHibernate Profiler 告诉我们,我们还在母版页中打开和关闭了一个 session (在 using block 中),因为需要检查当前用户的某些权限,所以每个请求打开两个 session 。我已经重构了它,所以现在它不是在页面父类(super class)中打开 session ,而是在 Application_BeginRequest 上的 global.asax 中打开 session ,并在 Application_EndRequest 上再次关闭它,其中 session 放置在 HttpContext.Current.Items 中。
但没有确定的方法来测试这是否可以解决问题。
最佳答案
Stamppot,感谢您将此问题发布到 StackOverflow;如您所知,在网络上找不到太多有关此错误消息的其他信息。几个月前,我的团队在一个使用 NHibernate 和 log4net 的 Web 应用程序中遇到了类似的问题。 (StringTemplate 也可能参与其中。)我们通过将 Console.Out/Error 重定向到 Global.ascx.cs 中的 Application_Start() 事件处理程序中的空流(有效地禁用它们)来“修复”该问题:
protected void Application_Start(object sender, EventArgs e)
{
Console.SetOut(new System.IO.StreamWriter(System.IO.Stream.Null));
Console.SetError(new System.IO.StreamWriter(System.IO.Stream.Null));
}
详细信息:在我们的例子中,“可能的竞争条件...”错误与负载有关。在生产服务器上,这种异常会偶尔出现,每次都会导致工作进程崩溃。最终我们找到了如何重现它,方法是运行一个脚本,在短时间内用大量请求淹没 Web 应用程序。当与 NHibernate/StringTemplate/log4net 源代码相关时,异常堆栈跟踪指出在各种情况下使用 Console.Out/Error 方法进行日志记录。出现这样的错误似乎是一个奇怪的地方——这些方法不是considered to be thread-safe?吗?但是,在我们应用上述解决方法后,问题立即消失,并且此后再也没有出现过。不幸的是,其他优先事项使我们无法深入挖掘——但无论问题的根本原因是什么,它都没有以任何其他方式表现出来。
关于.net - 加载实体时的 nhibernate 竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12638810/
我正在努力处理查询的 WHERE 部分。查询本身包含一个基于两个表中都存在的 ID 的 LEFT JOIN。但是,我要求 where 语句仅返回其中一列中存在的最大单个结果。目前我返回连接中的所有值,
我有这个代码来改变文件系统的大小。问题是,即使满足 if 条件,它也不会进入 if 条件,而我根本没有检查 if 条件。它直接进入 else 条件。 运行代码后的结果 post-install-ray
假设我有一个包含 2 列的 Excel 表格:单元格 A1 到 A10 中的日期和 B1 到 B10 中的值。 我想对五月日期的所有值求和。我有3种可能性: {=SUM((MONTH(A1:A10)=
伪代码: SELECT * FROM 'table' WHERE ('date' row.date 或 ,我们在Stack Overflow上找到一个类似的问题: https://stackove
我有下面这行代码做一个简单的查询 if ($this->fulfilled) $criteria->addCondition('fulfilled ' . (($this->fulfilled
如果在数据库中找到用户输入的键,我将尝试显示“表”中的数据。目前我已将其设置为让数据库检查 key 是否存在,如下所示: //Select all from table if a key entry
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 5 年前。 Improve th
在MYSQL中可以吗 一共有三个表 任务(task_id、task_status、...) tasks_assigned_to(ta_id、task_id、user_id) task_suggeste
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
下面两个函数中最专业的代码风格是什么? 如果函数变得更复杂和更大,例如有 20 个检查怎么办? 注意:每次检查后我都需要做一些事情,所以我不能将所有内容连接到一个 if 语句中,例如: if (veh
我在 C# 项目中使用 EntityFramework 6.1.3 和 SQL Server。我有两个查询,基本上应该执行相同的操作。 1. Exams.GroupBy(x=>x.SubjectID)
我试图在 case when 语句中放入两个条件,但我在 postgresql 中遇到语法错误 case when condition 1 and condition 2 then X else Y
我正在构建一个连接多个表的查询,一个表 prodRecipe 将包含某些行的数据,但不是全部,但是 tmp_inv1 将包含所有行的计数信息。问题是,tmp_inv1.count 取决于某个项目是否在
我有一个涉及 couples of rows which have a less-than-2-hours time-difference 的查询(~0.08333 天): SELECT mt1.*,
我有一个包含许多这样的 OR 条件的代码(工作正常)来检查其中一个值是否为空,然后我们抛出一条错误消息(所有这些都必须填写) } elsif ( !$params{'account'}
我有一个名为 spGetOrders 的存储过程,它接受一些参数:@startdate 和 @enddate。这将查询“订单”表。表中的一列称为“ClosedDate”。如果订单尚未关闭,则此列将保留
在代码中,注释部分是我需要解决的问题...有没有办法在 LINQ 中编写这样的查询?我需要这个,因为我需要根据状态进行排序。 var result = ( from contact in d
我正在尝试创建一个允许省略参数的存储过程,但如果提供了参数,则进行 AND 操作: CREATE PROCEDURE MyProcedure @LastName Varchar(30)
我正在寻找一种方法来过滤我的主机文件中的新 IP 地址。我创建了一个脚本,每次我用来自矩阵企业管理器的数据调用它时都会更新我的主机文件。它工作正常。但是我必须找到一个解决方案,只允许更新 10.XX.
所以我正在做一种 slider ,当它完全向下时隐藏向下按钮,反之亦然,当向上按钮隐藏时,我遇到了问题。 var amount = $('slide').attr('number'); $('span
我是一名优秀的程序员,十分优秀!