回滚后的NHibernate 3会话状态()

Luk*_*uka 6 nhibernate session transactions rollback

我有个问题.

using (var tran = repository.Session.BeginTransaction())
{
    try
    {
        repository.Save(entity);
        tran.Comit();
    }
    catch(Exception)
    {
        tran.Rollback();
        throw;
    }    
}

using (var tran = repository.Session.BeginTransaction())
{
    try
    {
        repository.GetById(id);
        tran.Comit();
    }
    catch(Exception)
    {
        tran.Rollback();
        throw;
    }    
}
Run Code Online (Sandbox Code Playgroud)

当我尝试在异常之后和tran.rollback()第一个using块中通过ID获取实体时,我得到更新异常.所以NHibernate试图从using第二个using块的第一个块更新实体.

为什么?我做了tran.Rollback().我也必须这样做Session.Clear()吗?

gdj*_*gdj 15

根据Hibernate的API,当Hibernate Session抛出异常时,您必须关闭Session并创建一个新的Session.此外,当您回滚Hibernate事务时,您不能在以后提交它或刷新会话 - 您必须在新的会话中重新开始.

特别是(这是一个实现细节所以不要依赖它),在回滚之后,Hibernate Session仍然有自事务开始以来创建/修改的实体 - Hibernate没有通过你的实体并恢复你所做的所有更改.因此,如果您回滚事务然后刷新会话,Hibernate将提交您认为已回滚的实体更改.如果你想通过试图破解这种行为(例如清除会话)来玩火,请注意.最好重新开始一个新的Session.

  • @Luka,因为你正在使用每次调用会话,所以有一个每次调用的事务(每个会话事务)是有意义的.这将为上下文工作单元提供服务,其中每个调用都没有潜在的副作用:如果查询在调用中失败,则将回滚在调用中完成的所有数据库操作. (2认同)