asp.net – 与蜘蛛交易相关的各种NHibernate错误
我们有一个ASP.Net 4 / MVC 3混合Web应用程序,它使用NInject 3和(Fluent)NHibernate 3.2. DB是SQL Server 2008 R2.服务器是6核28 GB
Windows 2008 64位服务器.
我们的客户最近开始使用蜘蛛工具测试该网站.一旦站点遇到蜘蛛产生的负载,我们的日志开始填满异常. 我们看到来自NHibernate的各种错误,包括以下一些错误: > NHibernate.TransactionException:提交因SQL异常而失败—> System.Data.SqlClient.SqlException:无法执行事务操作,因为存在处理此事务的挂起请求. 仅举四个例子.所有这些都有类似的风格 – 它们似乎都与ADO.Net作为NHibernate基础的交易管理有关. 现在,我们NH实施的一些细节: > SessionFactory是静态的; 以下是我们的存储库中的两种方法. public T GetById<T>(int id) { using (var t = Session.BeginTransaction()) { var entity = Session.Get<T>(id); t.Commit(); return entity; } } public void Add<T>(T entity) { using (var t = Session.BeginTransaction()) { Session.Save(entity); t.Commit(); } } 我的问题很简单:出了什么问题?是什么导致了交易之间或者我们的域名在我们的域名中解除的各种数据相关操作之间的这些明显冲突? 更新:这是我们的完整配置: public FluentConfiguration BuildConfiguration(string connectionString) { var sqlConfig = MsSqlConfiguration.MsSql2008.ConnectionString(connectionString).AdoNetBatchSize(30); var config = Fluently.Configure().Database(sqlConfig); var entityMapping = AutoMap.AssemblyOf<User>(new AutomappingConfiguration()) .USEOverridesFromAssemblyOf<UserMappingOverride>() .AddMappingsFromAssemblyOf<TableNamingConvention>() .Conventions.AddFromAssemblyOf<TableNamingConvention>(); var cqrsMapping = AutoMap.AssemblyOf<AdvertView>(new QueryAutomappingConfiguration()) .USEOverridesFromAssemblyOf<AdvertViewMappingOverride>(); config.Mappings(c => c.AutoMappings.Add(entityMapping)); config.Mappings(c => c.AutoMappings.Add(cqrsMapping)); config.Mappings(c => c.HbmMappings.AddFromAssemblyOf<AdvertView>()); config.ExposeConfiguration(c => c.SetProperty(Environment.TransactionStrategy,typeof(AdoNetTransactionFactory).FullName)); config.CurrentSessionContext<WebSessionContext>(); return config; } 更多代码为你们和gals.以下是IoC Container配置的相关部分. var domainEntityBootstrapper = new DomainEntitySessionBootStrapper("Domain","NHibernate.ISession.Domain",_enableLucine,HttpContextItemsProvider); Bind<ISessionFactory>().ToMethod(domainEntityBootstrapper.CreateSessionFactory).InSingletonScope().Named(domainEntityBootstrapper.Name); Bind<ISession>().ToMethod(domainEntityBootstrapper.GetSession).InRequestScope(); var queryBootstrapper = new QueryEntitySessionBootStrapper("Query","NHibernate.ISession.Query",HttpContextItemsProvider); Bind<ISessionFactory>().ToMethod(queryBootstrapper.CreateSessionFactory).InSingletonScope().Named(queryBootstrapper.Name); Bind<ISession>().ToMethod(queryBootstrapper.GetSession).WhenInjectedInto(typeof (QueryExecutor)).InRequestScope(); 这里是来自这些SessionBootstrappers的基类的GetSession()方法的代码(请注意,CreateSessionFactory方法调用上面的BuildConfiguration方法,然后调用BuildSessionFactory()). public virtual ISession GetSession(IContext context) { var items = GetHttpContextItems(); var session = default(ISession); var sessionExists = items.Contains(SessionKey); if (!sessionExists) { session = context.Kernel.Get<ISessionFactory>(Name).OpenSession(); items.Add(SessionKey,session); } else { session = (ISession)items[SessionKey]; } return session; } // a Func which serves access to the HttpContext.Current.Items collection private Func<IDictionary> GetHttpContextItems { get; set; } 请注意,我们使用两个会话,一个用于普通域de / hydration,一个用于CQRS,因此Container中的绑定对. 解决方法
错误消息表明您没有正确管理事务.我认为根本原因是你正在处理存储库方法中的事务,在我看来这是一个非常糟糕的设计.您的存储库应该将一个ISession注入其构造函数中,并且您的控制器应该具有它们依赖于注入其构造函数的任何存储库.使用Ninject可以轻松完成这一切.使用此方法,您可以使用每个请求事务或(更好地imo)管理操作方法中的事务.
以下是我在NinjectWebCommon中使用Ninject设置NHibernate的方法.您的问题的根本原因可能是您在请求范围中绑定了ISession并将其存储在HttpContext中,这是不必要的.我也很困惑为什么你有两组Domain和Query绑定. private static void RegisterServices(IKernel kernel) { kernel.Bind<ISessionFactory>().ToProvider(new SessionFactoryProvider()).InSingletonScope(); kernel.Bind<ISession>().ToProvider(new SessionProvider()).InRequestScope(); } private class SessionFactoryProvider : Provider<ISessionFactory> { protected override ISessionFactory CreateInstance(IContext context) { // create and configure the session factory // I have a utility class to do this so the code isn't shown return nhibernateHelper.BuildSessionFactory(); } } private class SessionProvider : Provider<ISession> { protected override ISession CreateInstance(IContext context) { var sessionFactory = context.Kernel.Get<ISessionFactory>(); var session = sessionFactory.OpenSession(); session.FlushMode = FlushMode.Commit; return session; } } 使用事务的示例控制器操作.管理存储库之外的事务非常重要,原因如下: >允许多个存储库参与事务 public ActionResult EditDocuments(int id,string name) { using (var txn = _session.BeginTransaction()) { var summary = _characterizationRepository .GetCharacterization(id) .AsCharacterizationSummaryView() .ToFutureValue(); var documents = _characterizationRepository .GetCharacterization(id) .SelectMany(c => c.Documents) .OrderBy(d => d.FileName) .AsDocumentSelectView(true) .ToFuture(); if (summary.Value == null) { throw new NotFoundException(_characterizationRepository.ManualId,"Characterization",id); } CheckSlug(name,summary.Value.Title); var model = new DocumentSectionEditView() { CharacterizationSummary = summary.Value,Documents = documents.ToArray() }; txn.Commit(); return View(model); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 什么时候Request.Form [“name”]为null并且当一
- ASP.NET获取当前用户名
- asp.net – 如何在南希显示我的404页面?
- asp.net-membership – 如何获得会员资格的用户ID?
- asp.net-mvc-4 – 使用KNOCKOUT.JS和ASP.NET MVC 4进行级联
- asp.net – 如何在会话超时或结束时注销用户
- asp.net-mvc-3 – 如何在MVC 3 RAZOR中动态设置图像路径
- ASP.NET MVC 3 – 隔离HTML.Raw输出
- asp.net – IIS Express(WebMatrix)打开外部连接
- asp.net-mvc – ASP.NET MVC帐户控制器使用指南?
- asp.net-mvc – MVC最后一次在向用户呈现之前更改
- [ASP NET MVC] 表单 Partial View / Editor Temp
- asp.net-mvc – ASP.Net MVC 3 – HandleError属
- asp.net-mvc-3 – 带有asp.net mvc 3的$ajax内的
- asp.net-mvc – ASP MVC3 – 如何从数据库加载页
- asp.net-mvc – UserManager.AddPasswordAsync()
- IBatis.Net 老技术新研究
- IIS和ASP.Net Web开发服务器之间的行为差??异?
- asp.net – 在窗口调整大小或在标签之间切换之前
- 休息 – 使用IHttpActionResult时如何获取帮助文