【问题标题】:How do transactions work in nhibernate?事务如何在 nhibernate 中工作?
【发布时间】:2011-06-05 16:39:43
【问题描述】:

我刚开始学习 nHibernate,我对事务感到困惑。我知道 nhibernate 会跟踪会话中对持久对象的所有更改,并且这些更改会在提交时发送到数据库,但是事务的目的是什么?

如果我将代码包装在“使用事务”块中并调用 commit,它是仅提交事务中发生的对象更改,还是提交自上次提交刷新以来会话中发生的所有更改?

【问题讨论】:

    标签: c# nhibernate orm


    【解决方案1】:

    事务的目的是确保您不会提交带有脏数据或错误的会话。考虑一个非常简单的订购书的交易案例。

    您可能会执行以下操作: a) 检查该书此时是否存在。 b) 阅读客户的详细信息,看看他的购物车中是否有任何东西。 c) 更新图书数量 d) 输入订单

    现在考虑在输入订单时遇到错误的情况,因为您希望回滚其他更改,即在您回滚事务时。

    你是怎么做到的?那么有很多方法。 Web 应用程序的一种方法是监视 HTTP 错误对象,如下所示:

    if(HttpContext.Current != null && HttpContext.Current.Error != null)
    transaction.Rollback();
    

    理想情况下,您不应该通过使用显式事务块来破坏您的工作单元模式。尽量避免这样做

    【讨论】:

    • 我很困惑,这篇文章说我应该对所有事情都使用显式事务,但你说使用这些会破坏“工作单元”模式。 nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions
    • 我相信他的意思是事务不应该直接在服务/存储库方法中使用。更好的方法是创建一个 ActionFilter 或一个 HTTP 模块来启动事务并根据是否存在异常来提交/回滚。
    • Matthew 的第一条评论指出,即使您没有明确设置事务,nhibernate 仍然会将整个事物作为事务发送。这与在 HttpModule 中显式设置一个有何不同?
    【解决方案2】:

    如果您不使用事务,那么任何时候 NHibernate 发送一个批次,这本身就是一个事务。我不确定 session.Flush() 是否使用批处理。让我们假设它确实如此。您对 session.Flush() 的第一次调用将导致事务。假设您对刷新的第二次调用导致错误。第一次刷新的更改将保留在数据库中。

    另一方面,如果您使用的是显式事务,则可以调用一百万次刷新,但如果您回滚事务(可能是因为第 10 万次刷新引发了错误),那么所有刷新都会回滚。

    希望这是有道理的。

    【讨论】:

    • 我仍然难以掌握的是对象跟踪。显式事务如何影响全局对象跟踪?假设一个持久对象在显式事务之外更改(现在很脏),但我还没有提交。接下来是一个显式事务,它运行一些查询然后提交。对显式事务之外的对象的更改也会被提交吗?这让我很困惑。
    猜你喜欢
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多