【问题标题】:Transactions for read-only DB access?只读数据库访问的事务?
【发布时间】:2010-10-23 12:23:05
【问题描述】:

对于使用事务从数据库中读取,似乎有非常不同的意见。

引自 DeveloperWorks 文章Transaction strategies: Models and strategies overview

如果你需要一笔交易 你只读取数据?答案 是你没有。开始一个 执行只读事务 操作增加了的开销 处理线程并可能导致共享 数据库上的读锁(取决于 关于您使用的数据库类型 以及设置的隔离级别 到)。

作为相反的意见,Hibernate 文档Non-transactional data access and the auto-commit mode 有以下引用

我们的建议是不要使用 应用程序中的自动提交模式,以及 仅应用只读事务 当有明显表现时 受益或未来代码更改时 极不可能。总是喜欢 常规 ACID 事务分组 您的数据访问操作, 不管你是阅读还是 写入数据。

在 EclipseLink 邮件列表here 上也有类似的争论。

那么真相在哪里?用于阅读最佳实践的交易是否是最佳实践?如果两者都是可行的解决方案,那么使用事务的标准是什么?

据我所知,只有隔离级别高于“已提交读”时才会有所不同。这是正确的吗?

有什么经验和建议?

【问题讨论】:

    标签: database transactions data-access


    【解决方案1】:

    如果您想为查询设置特定超时而不是默认超时,或者如果您想更改隔离级别,则只读操作需要事务。

    此外,每个数据库(不知道异常)都会在内部为每个查询启动一个事务。当不需要回滚时,一般认为不回滚事务。

    DBA 可能正在监视回滚活动,在这种情况下,任何默认的回滚行为都会惹恼他们。

    因此,无论您是否启动事务,都会使用事务。如果您不需要它们,请不要启动它们,但不要对只读操作进行回滚。

    【讨论】:

      【解决方案2】:

      Steven Devijver 提供了一些启动事务的充分理由,即使这些操作只是读取数据库:

      • 设置超时或锁定模式
      • 设置隔离级别

      标准 SQL 要求,如果当前没有正在进行的事务,则即使是查询也必须启动新事务。有些 DBMS 不会发生这种情况——例如,那些具有自动提交模式的 DBMS(语句启动事务并在语句完成后立即提交)。其他 DBMS 默认情况下使语句原子化(有效地自动提交),但使用诸如“BEGIN WORK”之类的语句启动显式事务,取消自动提交直到下一次 COMMIT 或 ROLLBACK(IBM Informix Dynamic Server 就是这样 - 当数据库不是 MODE 时ANSI)。

      我不确定永远不要回滚的建议。它对只读事务没有影响,并且在某种程度上它会惹恼您的 DBA,那么最好避免 ROLLBACK。但是,如果您的程序在没有执行 COMMIT 的情况下退出,DBMS 应该对您不完整的事务执行 ROLLBACK - 当然如果它修改了数据库,并且(为简单起见)即使您只选择了数据。

      总的来说,如果要改变一系列操作的默认行为,请使用事务,即使事务是只读的。如果您对默认行为感到满意,那么使用事务并不重要。如果您的代码要在 DBMS 之间移植,最好假设您需要一个事务。

      【讨论】:

        【解决方案3】:

        首先,这听起来像是过早的优化。正如 Steven 所指出的,大多数健全的数据库无论如何都会让你进入一个事务,而他们真正做的只是在每个语句之后调用 commit。所以从这个角度来看,自动提交的性能可能会降低,因为每个语句都必须启动一个新事务。或者可能不是。只有基准测试才能说明问题,我敢打赌它不会对您的应用程序产生任何影响。

        您希望始终使用事务的一个原因是保护的一致性。如果您仅在“需要”时才开始手动声明事务,那么您将在关键时刻忘记。或者那些所谓的只读操作突然不是,或者是因为后来的程序员没有意识到它应该是,或者因为你的代码调用了一个具有隐藏写入的函数。例如,我将命令行数据库客户端配置为不自动提交。这意味着我可以在删除查询的同时仍然回滚。

        正如所指出的,存在隔离级别。这使您可以进行多次读取,而不必担心是否有其他进程在它们之间写入了您的数据,从而使您的读取有效地原子化。这将使您免于调试竞争条件的许多小时。

        最后,您通常可以将事务设置为只读。这会检查您的假设,如果尝试写入,则会出错。

        Here's a nice article summing it all up. 细节是 Oracle 特定的,但概念是通用的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-29
          • 2010-09-22
          • 2011-08-22
          • 1970-01-01
          • 2016-01-03
          • 2012-10-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多