在只有选择的事务中,提交和回滚之间是否存在差异?

时间:2008-10-13 16:04:30

标签: sql oracle transactions commit rollback

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

请注意我使用的是Oracle,但我猜其他数据库也有类似的行为。此外,我无法对开始交易的要求做任何事情,代码库的那部分不在我手中。

7 个答案:

答案 0 :(得分:12)

数据库通常会保留前映像日志(事务之前的日志)或后映像日志(事务完成时的内容)。如果它保留了前映像,则必须还原在回滚。如果它保留了一个后映像,则必须在提交时替换数据。

Oracle同时拥有日志和回滚空间。事务日志累积了后来由DB编写者编写的块。由于这些是非同步的,因此几乎没有任何与DB编写器相关的事务对您的事务有任何影响(如果队列填满,那么您可能需要等待。)

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

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

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

答案 1 :(得分:8)

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

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

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

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

答案 2 :(得分:3)

一般来说,COMMIT比ROLLBACK快得多,但是在你没有做任何事情的情况下,它们实际上是相同的。

答案 3 :(得分:3)

文件说明:

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

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

如果你想要选择做一个或另一个,那么你也可以做一个与什么都不做的一样,然后提交它。

答案 4 :(得分:1)

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

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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