2009-12-29 141 views

回答

54

是,在事务内部的人可以看到其他先前的插入/更新/删除语句事务所作出的更改,则交易不能外SELECT语句....

如果你问关于隔离级别是什么,然后理解 - 所有选择语句(嘿,所有类型的语句), - 在事务中是。明确地在交易中的一个和站在它自己的交易之间的唯一区别在于,独自站立的交易在其执行之前立即开始交易,并且在执行之后立即提交或回滚,

而事务中的显式地可以(因为它具有Begin Transaction语句)可以在该Select事件之前或之后发生在同一个事务中发生的其他语句(插入/更新/删除,无论)。

因此,无论隔离级别设置为何,这两个选择(在显式事务内部或外部)都将处于正在该隔离级别上运行的事务中。

加法: 以下是针对SQL Server,但所有数据库必须以相同的方式工作。在SQL Server中,查询处理器始终处于3种交易模式之一,AutoCommit,隐式明确

AutoCommit是SQL Server数据库引擎的默认事务管理模式。 ..每个Transact-SQL语句在完成时都已提交或回滚。 ...如果一个语句成功完成,它将被提交;如果遇到任何错误,则会回滚。这是默认设置,并且是在评论中@ Alex的问题的答案。

Implicit Transaction模式,” ......当前事务被提交或回滚后的SQL Server数据库引擎自动启动一个新的事务你什么都不做划定一个事务的开始。你只提交或隐式事务模式生成连续的事务链......“请注意,斜体代码片段针对每个事务,无论是单个事务还是多个事务。

当您使用BEGIN TRANSACTION声明明确启动事务时,引擎被置于Explicit Transaction模式。然后,每个语句都在该事务中执行,直到您明确终止事务(使用COMMITROLLBACK)或者发生导致引擎终止和回滚的故障。

+1

我想他是问有没有区别:“select ...”和“start transaction; select ...; stop transaction;” – tster 2009-12-29 20:21:21

+0

很好说! – 2009-12-29 20:29:41

+0

很好的回答。我在寻找这些信息 – Davita 2011-03-02 13:10:44

2

READ COMMITTED隔离级别是关于已写入的记录。它与这个select语句是否在事务中无关(除了在同一事务中写入的那些事件)。

5

是的,有一点区别。对于MySQL,直到第一次查询时,数据库才会真正以快照开头。因此,重要的不是开始,而是交易中的第一个陈述。如果我做到以下几点:

#Session 1 
begin; select * from table; 

#Session 2 
delete * from table; #implicit autocommit 

#Session 1 
select * from table; 

然后,我会得到同样的事情在会话中的一个两次(这是在表之前,我删除了信息)。当我结束会话的事务(提交,开始或回滚)并再次检查该会话时,表将显示为空。

+1

对于MySQL InnoDB,你是绝对正确的 - 对于InnoDB READ COMMITTED隔离模式来保证一致的读取。但是,在一般情况下,您可能会遇到不可重复的读取,在这种情况下,可以归结为两种情况(自动提交与待处理事务)能够看到其他事务所做的修改,前提是这些更改已落实。 – 2009-12-29 20:33:22

3

如果你的数据库(或者你的select语句中使用的所有表的底层存储引擎)是事务性的,那么就没有办法在“事务之外”执行它。

也许你的意思是“以自动提交模式运行它”,但这不同于“不交易”。在后一种情况下,它仍然在事务中运行,只是在您的语句被完成后,事务立即结束。

因此,在这两种情况下,在运行期间,单个select语句将在READ COMMITTED级别与其他事务隔离。

现在这对于您的READ COMMITTED事务隔离级别意味着什么:或许令人惊讶的是,没有那么多。

READ COMMITTED表示您可能遇到不可重复的读取:在同一事务中运行多个select语句时,可能会在某个时间点选择的行被修改并由另一个事务进行合并。稍后在相同的挂起事务中重新执行select语句时,您将能够看到这些更改。在自动提交模式下,这2个选择语句将在他们自己的事务中执行。如果另一个事务会修改并提交第一次选择的行,那么当您第二次执行该语句时,您将能够看到这些更改。