21

我们在我公司使用的内部应用程序框架使得有必要将每个 SQL 查询放入事务中,即使我知道没有任何命令会在数据库中进行更改。在会话结束时,在关闭连接之前,我提交事务以正确关闭它。我想知道如果我回滚它是否有任何特别的区别,尤其是在速度方面。

请注意,我使用的是 Oracle,但我猜其他数据库也有类似的行为。此外,我对开始交易的要求无能为力,代码库的那部分不在我的掌控之中。

4

7 回答 7

13

数据库通常保留前映像日志(事务之前的状态)或后映像日志(事务完成时的状态。)如果保留前映像,则必须在回滚时恢复. 如果它保留残像,则必须在提交时替换数据。

Oracle 既有日志空间,也有回滚空间。事务日志累积块,稍后由 DB 写入者写入。由于这些是异步的,几乎没有任何与数据库写入器相关的内容对您的事务有任何影响(如果队列已满,那么您可能需要等待。)

即使对于仅查询事务,我也愿意打赌在 Oracle 的回滚区域中存在一些事务记录保存。我怀疑回滚需要 Oracle 在确定没有任何实际回滚之前需要做一些工作。我认为这与您的交易同步。在回滚完成之前,您不能真正释放任何锁。[是的,我知道您在事务中没有使用任何东西,但锁定问题是为什么我认为必须完全释放回滚,然后才能释放所有锁,然后您的回滚就完成了。]

另一方面,提交或多或少是预期的结果,我怀疑丢弃回滚区域可能会稍微快一些。您没有创建任何事务条目,因此数据库编写器甚至永远不会醒来检查并发现无事可做。

我还希望,虽然提交可能会更快,但差异会很小。如此微小,以至于您甚至可能无法在并排比较中测量它们。

于 2008-10-13T16:46:18.060 回答
8

我同意之前的答案,在这种情况下 COMMIT 和 ROLLBACK 之间没有区别。确定没有任何内容可提交所需的 CPU 时间与确定没有任何内容可回滚所需的 CPU 时间之间的差异可能可以忽略不计。但是,如果差异可以忽略不计,我们可以放心地忘记它。

但是,值得指出的是,在单个事务的上下文中执行大量查询的会话与在一系列事务的上下文中执行相同查询的会话之间存在差异。

如果客户端启动事务,执行查询,执行 COMMITor ROLLBACK,然后启动第二个事务并执行第二个查询,则不能保证第二个查询将观察到与第一个查询相同的数据库状态。有时,维护数据的单一一致视图至关重要。有时,获取数据的最新视图至关重要。这取决于你在做什么。

我知道,我知道,OP没有问这个问题。但是有些读者可能会在他们的脑海中问这个问题。

于 2008-10-13T16:43:16.663 回答
3

一般来说,COMMIT 比 ROLLBACK 快得多,但在你什么都不做的情况下,它们实际上是相同的。

于 2008-10-13T16:15:40.760 回答
3

该文件指出:

  • Oracle 建议您在与 Oracle 数据库断开连接之前,使用 COMMIT 或 ROLLBACK 语句显式结束应用程序中的每个事务,包括最后一个事务。如果没有显式提交事务,程序异常终止,那么最后一个未提交的事务会自动回滚。大多数 Oracle 实用程序和工具的正常退出会导致提交当前事务。Oracle 预编译器程序的正常退出不会提交事务,而是依赖 Oracle 数据库回滚当前事务。

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/statements_4010.htm#SQLRF01110

如果你想选择做一个或另一个,那么你还不如做一个和什么都不做一样的事情,然后就去做。

于 2008-10-13T22:18:10.310 回答
1

好吧,我们必须考虑 SELECT 在 Oracle 中返回的内容。有两种模式。默认情况下,SELECT 返回数据,因为数据在 SELECT 语句开始执行的那一刻开始执行(这是 READ COMMITTED 隔离模式的默认行为,默认的事务模式)。因此,如果在发出 SELECT 之后执行了 UPDATE/INSERT,则结果集中将不可见。

如果您需要比较两个结果集(例如总账应用程序的债务方和贷方方),这可能会成为问题。为此,我们有第二种模式。在该模式下,SELECT 返回当前事务开始时的数据(READ ONLY 和 SERIALIZABLE 隔离级别的默认行为)。

因此,至少有时需要在事务中执行 SELECT。

于 2008-10-21T20:27:06.270 回答
0

由于您没有做过任何 DML,我怀疑 Oracle 中的 COMMIT 和 ROLLBACK 之间没有区别。无论哪种方式,都无事可做。

于 2008-10-13T16:07:10.463 回答
0

我认为 Commit 会更有效;因为通常您希望提交大多数数据库事务;所以你会认为数据库针对这种情况进行了优化(而不是试图更有效地进行回滚)。

于 2011-04-07T10:52:47.913 回答