【问题标题】:NHibernate Transactions on ReadsNHibernate 读取事务
【发布时间】:2009-11-01 15:42:30
【问题描述】:

我已阅读文档并解释了为什么强烈建议在 NH 中的读取操作中使用事务。但是,我还没有完全“购买”它。有人可以在不告诉我 RTFM(我已经做过)的情况下尝试解释它吗? ;)

【问题讨论】:

    标签: c# nhibernate transactions


    【解决方案1】:

    This post from one of the authors 可能会有你的答案:

    即使我们只是读取数据,我们 想要使用事务,因为 使用事务确保我们得到 来自数据库的一致结果。 NHibernate 假设所有访问 数据库是在一个 交易,强烈劝阻 任何会话的使用都没有 交易。

    撇开安全问题不谈 处理交易, 假设交易是 成本高昂,我们需要优化它们是 一个假的。如前所述, 数据库总是在运行 交易。并且数据库已经 高度优化以使用 交易。问题是什么 这是每个语句或每个批次。 有一些工作需要 要创建和处置一个 交易,并且必须按照 声明实际上比 按批次进行。

    【讨论】:

      【解决方案2】:

      其他人说的是真的,但是他们并没有指出自己不控制事务的问题是如果你在没有显式事务的情况下执行多个 NHibernate 操作,这些操作中的每一个都将发生在 单独的交易

      所以你很容易得到操作之间的不一致。通过显式启动 NHibernate 事务然后执行其中的操作,可以保证这些操作之间的一致性。

      当然,对于任何隐式为您启动事务的数据访问层都是如此,如果您不这样做的话。它不仅限于 NHibernate。

      【讨论】:

        【解决方案3】:
        var fooIdFromDb = ExecuteQuery("Select Id from Foo where something = somethingelse");
        var barsFromDb = ExecuteQuery("Select * from Bar where FooId = " + fooIdFromDB);
        

        如果其他事务从两个查询之间的 Bar 中删除行怎么办?您将遇到幻像数据的问题。这不是 NHibernate 特定的问题。在不使用事务的情况下,任何其他类型的数据库访问都会遇到同样的问题。您应该阅读有关交易的一般手册,而不是 NHiberante 手册。

        【讨论】:

          【解决方案4】:

          让我们关注如果您使用事务会发生什么。在处理结束时,但在开始读取数据(即视图)之前关闭会话是习惯性的,但不是强制性的。此方法在术语“Open Session in View”下传播(尽管它显然具有防止关闭前读取的模式)。这种模式通常用于 Web 应用程序,其中会话在请求到达时打开并在写入响应流之前关闭。

          (N)Hibernate 需要一个会话和一个事务。当您在不使用显式事务的情况下阅读时,将为您设置事务。在事务提交后读取时,行为取决于 NH 配置和驱动程序。

          ODBC 和 JDBC 都没有定义当连接关闭并且有未提交或未回滚的数据时会发生什么。重新打开连接时,可能会自动启动新事务。

          使用非事务性访问只能与在 NHibernate 配置中显式设置 auto-commit 一起使用。如果不是,则使用驱动程序的默认值,它可能有效,也可能无效。

          简而言之,当您在读取时不使用事务时,存在许多缺点和未定义的行为。它会经常工作,但这取决于配置、应用的模式和驱动程序。很有可能你得到LazyInitializationExceptions,这是在提交后读取而不打开新事务的常见结果。

          “最佳实践”是将一个事务用于读/写,另一个用于只读。这在上一个链接“我可以在一个会话中使用两个事务”部分中进行了简要描述,但需要更多的实现。

          这不仅是“使用事务进行读取”,还是:“使用与写入相同的事务进行读取”。 (然后,虽然这是真的,但实际应用程序将取决于您当前的模式、有多少层、缓存和配置)。

          更新:扩展了一些,消除了一些歧义

          【讨论】:

          • 您说:““最佳实践”是将一个事务用于读/写,另一个用于只读。”然后您说:“使用与写入相同的事务来读取“这是一个错字吗?
          • @DmytroLaptin,如果您只是读取,请使用事务,如果您正在读取写入/写入一个数据集,请使用事务,但如果您正在执行,请使用相同的两个都。虽然这是 5.5 年前写的,但我相信我试图表达的观点是,即使是只读数据,也要使用事务。所以不,我认为这不是错字,这两句话是相辅相成的。
          【解决方案5】:
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-30
          • 1970-01-01
          相关资源
          最近更新 更多