默认的READ COMMITTED隔离级别是否会使select语句在事务内部的行为与不在事务中的行为不同?
我正在使用MSSQL。
答案 0 :(得分:62)
是的,事务中的那个可以看到 事务中其他先前的Insert / Update / delete语句所做的更改;事务外的Select语句不能。
如果您要询问的是隔离级别的作用,那么请理解事务中的所有Select语句(嘿,所有类型的语句) - 。在事务中明确表示的事件与独立事件之间的唯一区别在于,独立的事务在执行事务之前立即启动事务,并在执行后立即提交或回滚;
而在事务中显式的那个可以(因为它有一个Begin Transaction语句)可以在同一个事务中发生其他语句(插入/更新/删除,无论如何)或者在Select语句之后。
因此无论隔离级别设置为什么,两者选择(显式事务内部或外部)都将处于以该隔离级别运行的事务中。
<强>加成强>: 以下是针对SQL Server的,但所有数据库必须以相同的方式工作。在SQL Server中,查询处理器始终处于3种交易模式之一, AutoCommit ,隐式或显式。
AutoCommit是SQL Server数据库引擎的默认事务管理模式。 ..每个Transact-SQL语句在完成时都会提交或回滚。 ... 如果语句成功完成,则提交;如果它遇到任何错误,它将被回滚。这是默认值,是评论中@ Alex的问题的答案。
在Implicit Transaction模式下,“... SQL Server数据库引擎自动在提交或回滚当前事务后启动新事务。您无需描述任何内容事务的开始;您只提交或回滚每个事务。隐式事务模式生成连续的事务链。...“请注意,斜体代码片段适用于每个事务,无论是单个还是多个语句事务。 / p>
当您使用BEGIN TRANSACTION
语句显式启动事务时,引擎将处于Explicit Transaction模式。然后,每个语句都在该事务中执行,直到您显式终止事务(使用COMMIT
或ROLLBACK
)或者发生导致引擎终止和回滚的故障。
答案 1 :(得分:6)
是的,有一点不同。对于MySQL,在第一次查询之前,数据库实际上并不是以快照开头。因此,重要的不是开始,而是交易中的第一个陈述。如果我执行以下操作:
#Session 1
begin; select * from table;
#Session 2
delete * from table; #implicit autocommit
#Session 1
select * from table;
然后我会在会话一中得到同样的东西(我删除它之前在表中的信息)。当我结束会话1的事务(提交,开始或回滚)并再次从该会话中检查时,该表将显示为空。
答案 2 :(得分:3)
如果你的数据库(或mysql,你的select语句中使用的所有表的底层存储引擎)是事务性的,那么根本就没有办法在“事务之外”执行它。
也许你的意思是“在自动提交模式下运行它”,但这与“非事务性”不同。在后一种情况下,它仍然在一个事务中运行,只是事务在你的语句被清理后立即结束。
因此,在这两种情况下,在运行期间,单个select语句将在READ COMMITTED级别与其他事务隔离。
现在这对您的READ COMMITTED事务隔离级别意味着什么:也许令人惊讶,不是那么多。
READ COMMITTED意味着您可能会遇到不可重复的读取:在同一事务中运行多个select语句时,您在某个特定时间点选择的行可能会被另一个事务修改和调用。稍后在同一个待处理事务中重新执行select语句时,您将能够看到这些更改。在自动提交模式下,这两个select语句将在它们自己的事务中执行。如果另一个事务已经修改并提交了您第一次选择的行,那么当您第二次执行该语句时,您也可以看到这些更改。
答案 3 :(得分:2)
READ COMMITTED隔离级别是关于已写入的记录。它与此select语句是否在事务中无关(除了那些在同一事务中写入的事物)。