7

在 NHibernate 3.0 中,FlushMode.Auto仅在环境事务下运行时不起作用(即,不启动 NHibernate 事务)。应该是?

using (TransactionScope scope = new TransactionScope()) 
{
    ISession session = sessionFactory.OpenSession();
    MappedEntity entity = new MappedEntity() { Name = "Entity", Value = 20 };
    session.Save(entity);

    entity.Value = 30;
    session.SaveOrUpdate(entity);

    // This returns one entity, when it should return none
    var list = session.
               CreateQuery("from MappedEntity where Value = 20").
               List<MappedEntity>();
}

(示例无耻地从这个相关问题中窃取)

在 NHibernate 源代码中,我可以看到它正在检查是否有正在进行的事务 (in SessionImpl.AutoFlushIfRequired),但相关方法 ( SessionImpl.TransactionInProgress) 不考虑环境事务 - 不像它的表亲ConnectionManager.IsInActiveTransaction,它确实考虑环境事务。

4

4 回答 4

6

好消息。感谢 Jeff Sternal(他很好地发现了问题)我更新了https://nhibernate.jira.com/browse/NH-3583并且感谢 NH 工作人员,在即将发布的 4.1 中已经有一个修复和一个拉取请求。 xx 这个问题将被修复。

于 2015-03-04T08:33:36.137 回答
3

您应该始终使用显式 NHibernate 事务。

using (TransactionScope scope = new TransactionScope()) 
using (ISession session = sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
    //Do work here
    transaction.Commit();
    scope.Complete();
}

我看到你也在 NH 开发者列表中写道 - 虽然这在未来可能会改变,但现在就是这样。

于 2011-03-05T23:24:20.653 回答
2

Diego 提供的答案在您拥有 oracle 数据库的情况下不起作用。(相关问题)。session.BeginTransaction 将失败,因为连接已经是事务的一部分。

看起来我们必须在我们的应用程序(WCF、NHibernate、Oracle)中围绕这个问题编写一些代码,但这感觉就像 NHibernate 应该提供开箱即用的东西。因此,如果有人有一个好的答案,那将不胜感激。

于 2011-03-07T08:47:28.273 回答
0

对我来说,我不知道背后的原因,但通过在会话处理之前强制会话刷新似乎对我有用。例如 using(session) { //做你的工作

session.Flush(); }

我验证了这适用于我的分布式事务,因为如果不这样做,我总是在处理 TransactionScope 时得到“事务已中止”。

即使将 session.FlushMode 设置为 Commit 也不适合我。

于 2014-02-26T12:15:07.803 回答