在我们公司使用的自有应用程序框架中,即使我知道没有任何命令会改变数据库,也必须将每个SQL查询放入事务中。在会话结束之前,在关闭连接之前,我提交事务以正确关闭它。我想知道如果我回滚事务是否会有特别的差异,尤其是在速度方面。
请注意,我正在使用Oracle,但我猜其他数据库具有类似的行为。此外,我无法对需要开始事务的要求做任何事情,这部分代码库不在我的控制范围内。
在我们公司使用的自有应用程序框架中,即使我知道没有任何命令会改变数据库,也必须将每个SQL查询放入事务中。在会话结束之前,在关闭连接之前,我提交事务以正确关闭它。我想知道如果我回滚事务是否会有特别的差异,尤其是在速度方面。
请注意,我正在使用Oracle,但我猜其他数据库具有类似的行为。此外,我无法对需要开始事务的要求做任何事情,这部分代码库不在我的控制范围内。
数据库通常保存一个前像日志(事务之前的状态)或后像日志(事务完成后的状态)。如果它保存了前像,那么在回滚时必须还原该值。如果它保存了后像,则在提交事件发生时必须替换数据。
Oracle拥有日志和回滚空间。事务日志累积块,稍后由DB编写器编写。由于这些是异步的,几乎没有任何与DB编写器相关的事情会影响您的事务(如果队列填满,则您可能需要等待)。
即使对于仅查询的事务,我也愿意打赌Oracle的回滚区域中也有一些小的事务记录跟踪。我怀疑回滚需要Oracle在确定实际上没有要回滚的内容之前进行一些工作。而我认为这与您的事务同步。在回滚完成之前,您无法释放任何锁定。[是的,我知道您在事务中没有使用任何锁定,但这个锁定问题就是我认为必须完全释放回滚,然后才能释放所有锁定,然后您的回滚才完成的原因。]
另一方面,提交是预期的结果,我认为放弃回滚区域可能会稍微快一些。由于您没有创建任何事务记录,因此DB编写器甚至不会醒来检查并发现没有要完成的任务。
我还预计,虽然提交可能更快,但差异将是微小的。如此微小,以至于您可能无法在并排比较中测量它们。
通常情况下,提交(COMMIT)比回滚(ROLLBACK)快得多,但在您什么也没做的情况下,它们实际上是相同的。
嗯,我们必须考虑Oracle中SELECT返回的内容。有两种模式。默认情况下,SELECT将数据作为在执行SELECT语句开始时该数据所呈现的样子返回(这是READ COMMITTED隔离模式(默认事务模式)的默认行为)。因此,如果在发出SELECT之后执行了UPDATE / INSERT,则不会在结果集中显示。
如果您需要比较两个结果集(例如总分类账应用程序的借方和贷方),则可能会遇到问题。对于这种情况,我们有第二种模式。在该模式下,SELECT将返回数据,就像当前事务开始时看起来一样(READ ONLY和SERIALIZABLE隔离级别的默认行为)。
因此,至少有时候需要在事务中执行SELECT。
由于您尚未执行任何DML操作,我怀疑在Oracle中提交(COMMIT)和回滚(ROLLBACK)之间没有区别。无论哪种方式,都不需要进行任何操作。