创建临时表、读取、删除后,我应该提交还是回滚事务?

4
为了选择与数百个ID相关的信息,我创建了一个临时表,将这些ID插入其中,将其与另一个表连接以选择匹配ID的行,然后删除临时表,而不是使用一条巨大的select语句。因此,这基本上是一个读取操作,没有对任何持久性数据库表进行永久更改。
我在事务中执行此操作,以确保完成后删除临时表。我的问题是...当我提交这样的事务时会发生什么,相对于让它回滚呢?
就性能而言...相对于提交事务,DB引擎是否需要做更多的工作来回滚事务?是否有区别,因为唯一的修改是针对临时表进行的?
这里有一个相关的问题,但没有回答我涉及临时表的具体情况:Should I commit or rollback a read transaction? 编辑(问题澄清):
不寻求在提交/回滚之前的建议。事务绝对必要。假设没有出现错误。假设我已经创建了一个临时表,假设我知道实际的写入tempdb的“工作”,假设我在事务中执行只读(select)操作,并假设我发布了一个删除语句来删除临时表。在所有这些之后...提交或回滚哪个更便宜,为什么?基于涉及临时表和其他只读操作的特定情况,DB引擎在这个时候可能会做什么其他工作,以区分提交和回滚?
2个回答

3
如果我们谈论本地临时表(即名称前缀为单个#),那么一旦关闭连接,SQL Server将删除该表。因此,假设您的数据层经过良好设计以使连接时间尽可能短,我不担心将临时表的创建包装在事务中。
我认为将表格包装在事务中可能会有轻微的性能差异,但我敢打赌,与保持事务打开更长的时间以等待创建和填充临时表所需的时间相比,这种差异是微不足道的。

我并不是在询问将其包装在事务中的性能。连接被连续传递给多个数据库API函数,并且它们使用共同的临时表名称/约定,因此保证删除临时表的事务是必要的。我感兴趣的是提交该事务或回滚该事务的影响。 - Triynko
@Triynko - 你对这个效果的哪方面感到好奇?其他代码是否可以访问临时表? - Thomas
@Triynko - 我想我明白你的困惑了。 即使某些事情在事务中,工作仍然会进行。 即使您在事务中创建临时表,填充它,做很多工作,然后回滚,将表放入tempdb并将数据写入磁盘的工作仍会进行,就好像它不在事务中一样。 唯一的区别是,在正常事务隔离级别下,此工作对于在事务之外使用代码的人不可见。 - Thomas
@Triynko - 还应该注意到,无论是在事务中还是不在事务中,与临时表相关的任何操作都不是纯粹在内存中完成的。它就像对任何其他普通表进行的任何其他操作一样。因此,打开一个事务并调用Create Table #Foo,仍会在磁盘上创建一个表。回滚您的事务,SQL Server将从磁盘中删除它(或者只是使其无法稍后处理),就像您调用了Drop Table #Foo一样。 - Thomas
@Thomas - 我已经明白创建临时表涉及磁盘访问(有时不同于表变量),但假设有一个事务,假设没有错误,并且我创建,执行只读操作(即选择),然后删除临时表.... 在那个时候,提交(Commit)和回滚(Rollback)的区别是什么?哪个会导致更多或更少的工作。 - Triynko
显示剩余2条评论

1

确保临时表被删除的更简单方法是使用 # 符号创建它。

CREATE TABLE #mytable ( rowID int, rowName char(30) )

# 告诉 SQL Server 这个表是一个本地临时表。这个表只对此 SQL Server 会话可见。当会话关闭时,表将自动删除。您可以像处理其他表一样处理此表,但也有一些例外情况。唯一真正的主要例外是您不能在临时表上拥有外键约束。其他内容均在 Books Online 中介绍。

临时表创建在 tempdb 中。

如果这样做,您就不必将其包装在事务中。


1
我说过我已经在使用 #temp 表了。但是连接被重复使用,因为它被传递给多个数据库 API 函数,所以有一个事务非常重要,在完成时显式删除表,要么通过进行删除和提交,要么通过回滚事务。我特别关注提交或回滚事务的影响(假设在提交之前肯定删除了表,在回滚之前可能删除了表)。 - Triynko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接