nHibernate:无法回滚完整操作

时间:2013-04-25 07:48:10

标签: nhibernate transactions fluent-nhibernate

我们在两个表,人员表和用户表之间分配了一个userobject。

public UserMap() 
{
   Table("Person");
   Id(x => x.PersonId, "PersonId");
   Map(x => x.Name, "Name");

   Join("User", s => {
      s.Fetch.Join();
      s.KeyColumn("PersonId");
      s.Map(x => x.Username, "Username");
      s.Map(x => x.Password, "Password");
   });
}

在进行插入时,nHibernate将首先将Name插入Person表,然后UsernamePassword插入User表。

当插入User - 表失败时(如尝试插入已使用用户名的用户),就会出现问题。事务失败,但不会回滚Person表中的插入。

    public User Save(User user)
    {
        var session = SessionHelper.GetCurrent();
        using (var dbTransaction = session.BeginTransaction())
        {
            try
            {
                session.SaveOrUpdate(user);
                dbTransaction.Commit();
            }
            catch (Exception)
            {

                dbTransaction.Rollback();
                throw;
            }                
        }

        return user;
    }

我们的SessionFactory也使用Fluent NHibernate设置

    public ISessionFactory BuildSessionFactory(string connectionString)
    {
        return Fluently.Configure().Database(OracleClientConfiguration.Oracle10.ConnectionString(c => c.Is(connectionString))
                                             .Provider<OracleDriverConnectionProvider>()
                                             .Driver<OracleDataClientDriver>()
                                             .ShowSql)
                                             .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>())
                                             .BuildSessionFactory();
    }

我已将失败的会话in a gist中的日志文件放入。 User实体在现实生活中稍微复杂一点,并且有一些认证内容正在进行,因此日志文件希望与绘制的图片1:1匹配...

3 个答案:

答案 0 :(得分:3)

似乎解决了类似的问题here。回滚事务时,NHibernate不会还原会话中的更改,即如果在回滚后刷新会话,您将遇到所描述的问题。为了确保实体不会发生变化,当您回滚时,您还必须关闭会话。

答案 1 :(得分:0)

仅在Person对象中添加User对象并仅保存Person对象。在Mapping文件中使用Cascade.All()。或第二个选项是使用TransactionScope。

答案 2 :(得分:-1)

您可以在使用roleld支持事务后使用session.Clear(),而不是关闭会话,这将删除所有挂起的写入并使会话与新的一样好。 这对我的应用程序起了作用。