我正在使用: - NHibernate 3.1版 - C#4.5 - 温莎城堡2.5.3
NHibernate在几分钟内写下了以下类型的错误:
[36]错误NHibernate.LazyInitializationException [(null)] - 初始化[.Core。#23] - 不能初始化代理 - 没有会话。
NHibernate.LazyInitializationException:初始化[.Core。#23] - 不能初始化代理 - 没有会话。
通常工作正常,系统运行数天和负载等等。但有时候(特别是在发生一些数据库异常之后),它只是变得不稳定,并且在很多分钟内不会在许多请求的过程中恢复。 IIS重置“修复”它。
你能告诉我应该研究的地方/可能的原因是什么?我可以做些什么来强制执行NHibernate重置等等?
代码:
private void ConfigureContainer()
{
_container = new DefaultTransientWindsorContainer();
_container.Register(Component.For<IRequestState>().ImplementedBy<PerHttpRequestState>(),
Component.For<ISessionFactory>()
.UsingFactoryMethod(x => InitNHibernate())
.LifeStyle.Singleton
);
_container.Install(FromAssembly.Containing<ZetesRegistry>());
_container.Install(FromAssembly.Containing<BusConnectorRegistry>());
Container.InitializeWith(_container);
}
更多代码:
internal class TransactionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
var uow = UnitOfWork.Start();
System.Web.HttpContext.Current.Items["uow"] = uow;
base.OnActionExecuting(actionContext);
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Exception == null)
{
var uow = System.Web.HttpContext.Current.Items["uow"] as UnitOfWork;
if (uow != null)
uow.Complete();
}
base.OnActionExecuted(actionExecutedContext);
}
}
提前谢谢!
更新1:
工作单位实施:
public class UnitOfWork : IUnitOfWork
{
public ISession Session { get; private set; }
public static IUnitOfWork Current
{
get { return Container.Resolve<IRequestState>().Get<IUnitOfWork>(); }
private set { Container.Resolve<IRequestState>().Store(value); }
}
private UnitOfWork(bool transactional)
{
var sessionFactory = Container.Resolve<ISessionFactory>();
Session = sessionFactory.OpenSession();
if (transactional) Session.BeginTransaction(IsolationLevel.ReadCommitted);
}
public static IUnitOfWork Start()
{
return Start(true);
}
private static IUnitOfWork Start(bool transactional)
{
if (Current != null)
throw new UnitOfWorkException("you cannot start more that one unit of work per request");
Current = new UnitOfWork(transactional);
return Current;
}
public static IUnitOfWork StartWithoutTransaction()
{
return Start(false);
}
public void Complete()
{
if (Session.Transaction.IsActive)
{
try
{
Session.Transaction.Commit();
}
catch
{
Session.Transaction.Rollback();
throw;
}
finally
{
Session.Close();
}
}
else
{
Session.Flush();
}
}
public void Dispose()
{
if (Session != null)
{
var transaction = Session.Transaction;
if (transaction != null
&& transaction.IsActive
&& !transaction.WasCommitted
&& !transaction.WasRolledBack)
{
transaction.Rollback();
}
Session.Dispose();
}
Current = null;
}
}
引发错误的代码:
public class ShippingsController : ApiController
{
private readonly IRepository _repository;
private readonly IPlanningDateProvider _planningDateProvider;
private readonly IStrategicPlanningProvider _strategicPlanningProvider;
public ShippingsController(IRepository repository, IPlanningDateProvider planningDateProvider, IStrategicPlanningProvider strategicPlanningProvider)
{
_repository = repository;
_planningDateProvider = planningDateProvider;
_strategicPlanningProvider = strategicPlanningProvider;
}
public Shippings Get(int id)
{
return Get(id, null);
}
public Shippings Get(int id, int? today)
{
var operationalPlanningCutOff = System.Web.Configuration.WebConfigurationManager.AppSettings["OperationalPlanningCutOff"];
if (string.IsNullOrEmpty(operationalPlanningCutOff))
operationalPlanningCutOff = "5";
var operationalPlanningCutOffHour = int.Parse(operationalPlanningCutOff);
if (today.HasValue && today.Value == 1)
return _repository.Query(new GetUrgentShippingInfoForCity(id)).UniqueResult();
return _repository.Query(new GetShippingInfoForCity(id, _planningDateProvider, operationalPlanningCutOffHour, _strategicPlanningProvider)).UniqueResult();
}
}
答案 0 :(得分:1)
不确定这是否相关但我注意到我需要为未命中onResultExecuted
的过滤器异常添加回滚。不记得为什么我需要这个,但在某些情况下,我注意到我的数据库可能会留下一个已启动但从未提交/回滚的事务,因为onResultExecuted
从未被命中,从而导致后续访问时出现数据库连接问题。也许你正在经历这种情况。您需要将其更改为适合您的UOW模式。
public void OnException(ExceptionContext filterContext)
{
if (CurrentSessionContext.HasBind(SessionFactory))
{
var currentTransaction = CurrentSessionContext.Unbind(SessionFactory).Transaction;
try
{
if (currentTransaction.IsActive)
currentTransaction.Rollback();
}
finally
{
currentTransaction.Dispose();
}
}
}
答案 1 :(得分:1)
我猜你实现了无效的会话管理。执行操作后,结果将转到查看引擎。查看从对象中读取一些属性,其中一些属性可能未初始化。需要会话来初始化它们,但是在操作后关闭它。所以我认为你必须选择:
答案 2 :(得分:0)
抱歉浪费了你的时间,但延迟加载配置中有一个拼写错误。该实体有2个属性Route And Routes,我们延迟加载Route而不是Routes。
对不起
此致