NHibernate 3.0:TransactionScope 和自动刷新

发布于 2024-10-20 05:34:12 字数 970 浏览 5 评论 0原文

在 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源代码中我可以看到它正在检查是否有正在进行的事务(在 SessionImpl.AutoFlushIfRequired 中),但相关方法 (SessionImpl.TransactionInProgress) 不考虑环境事务 - 与它的同类不同ConnectionManager.IsInActiveTransaction,它确实考虑环境事务。

In NHibernate 3.0, FlushMode.Auto does not work when running under an ambient transaction only (that is, without starting an NHibernate transaction). Should it?

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>();
}

(Example shamelessly stolen from this related question)

In the NHibernate source I can see that's it's checking whether there's a transaction in progress (in SessionImpl.AutoFlushIfRequired), but the relevant method ( SessionImpl.TransactionInProgress) does not consider ambient transactions - unlike its cousin ConnectionManager.IsInActiveTransaction, which does consider ambient transactions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蛮可爱 2024-10-27 05:34:12

好消息。感谢 Jeff Sternal(他很好地识别了问题),我更新了 https://nhibernate.jira.com/browse/NH-3583 感谢 NH 工作人员的帮助,已经有了修复程序和拉取请求,因此在即将发布的 4.1.xx 版本中,此问题将得到修复.

Good news. Thanks to Jeff Sternal (who nicely identified the problem) I updated https://nhibernate.jira.com/browse/NH-3583 and thanks to the NH staff, there's already a fix and a pull request so in the upcoming release 4.1.x.x this ISSUE will be fixed.

故人的歌 2024-10-27 05:34:12

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

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

我看到你也在 NH 开发列表中写道 - 虽然这将来可能会改变,但这就是现在的运作方式。

You should use an explicit NHibernate transaction always.

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

I see you also wrote in the NH dev list - while this can change in the future, that's how it works now.

七色彩虹 2024-10-27 05:34:12

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

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

The answer provided by Diego does not work in the case where you have an oracle database.
(releated question). The session.BeginTransaction will fail because the connection is already part of a transaction.

Looks like we have to write some code around this problem in our application (WCF,NHibernate, Oracle), but it just feels like something that NHibernate should provide out of the box.
So if anyone has a good answer, it would be really appreciated.

楠木可依 2024-10-27 05:34:12

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

session.Flush();
我验证了

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

即使将 session.FlushMode 设置为 Commit 对我来说也不起作用。

For me, I don't know the reason behind, but by forcing session flush before session is disposed seemed to worked for me. e.g.
using(session)
{
//do your work

session.Flush();
}

I verified that this works with my distributed transaction, since without doing this, I always get "transaction has aborted" when TransactionScope is disposed.

Even set session.FlushMode to Commit did NOT work for me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文