在事务中包含select语句有什么意义?

时间:2010-06-23 02:59:05

标签: sql-server-2005 tsql transactions

在事务中附加select语句有什么意义?我认为select语句只是来自数据库的“GET”数据,他们没有机会回滚一些东西,因为你无法改变数据。那么,这是否说我们永远不需要在事务中放置select语句?我是对的吗?

感谢。

7 个答案:

答案 0 :(得分:32)

你是对的:在标准isolation levelread committed,你不需要在事务中包装select语句。无论是否将它们包装在事务中,Select语句都将受到保护,不会被脏读。

connection 1:                          connection 2:

                                       begin transaction
                                       update user set name = 'Bill' where id = 1
select name from users where id = 1
                                       rollback transaction

select语句不会读取回滚更新:它们没有包含在事务中并不重要。

如果您需要repeatable reads,则在默认事务中包装选择无效:

connection 1:                          connection 2:

begin transaction
select name from users where id = 1
                                       update user set name = 'Bill' where id = 1
select name from users where id = 1
commit transaction

begincommit语句在这里没有帮助:第二个select 可能读取旧名称,或可能 strong>阅读新名称。

但是,如果您运行的隔离级别较高,例如serializablerepeatable read,则该组将受到保护,不会受到不可重复的读取:

connection 1:                          connection 2:

set transaction isolation level
    repeatable read
begin transaction
select name from users where id = 1
                                       update user set name = 'Bill' where id = 1
select name from users where id = 1              |
commit transaction                               |
                                                 |--> executed here

在这种情况下,update将阻止,直到第一个交易完成。

很少使用较高的隔离级别,因为它们会同时降低可在数据库中工作的人数。在最高级别serializable,报告查询会暂停所有更新活动。

答案 1 :(得分:7)

您可能在此交易期间正在进行其他更新/插入。如果访问数据库的代码是以可重用的方式编写的,那么您可能不会选择是否是事务中发生的唯一事情。

您的select语句可能希望在事务持续期间保持一致,并且与其他事务中发生的数据更改保持一致。您需要在系统中设置某种isolation level以防止脏读(读取另一个事务中未提交的更改)或幻像读取(读取另一个事务中的已提交更改)。

毋庸置疑,通过使用交易,您将获得更好的服务。

答案 2 :(得分:5)

单个SELECT语句以原子为开头 - 将其封闭在事务中是多余的。如果有多个SELECT语句,则保证在完成所有SELECT语句之前,没有人更改任何影响它们的任何内容。

答案 3 :(得分:3)

没有

事务为您提供了一致的数据库视图。

如果您希望选择在重复时返回相同的结果,则事务可以提供该结果。

答案 4 :(得分:3)

可能没有更改数据,但可能还有其他一些数据库连接。

答案 5 :(得分:2)

使用带有选择的交易的另一个原因:

在某些时候,您可能希望从参与事务的其他方法调用select方法,并且您希望select参与当前事务。如果您具有一致的设计,其中所有数据库操作都在事务中执行,则任何方法的调用者都知道它将参与其事务。

对于较小的前期开发成本,这可以帮助避免一些相当大的更改,以后尝试在if / when需求更改或添加新需求时进行交易。

答案 6 :(得分:0)

如果您确定所发生的一切都是SELECT,那么它不需要在事务中。你是否100%确定现在和永远更多它只是一个SELECT?