【发布时间】:2017-10-20 11:05:41
【问题描述】:
我已阅读文章 (https://www.simple-talk.com/sql/t-sql-programming/questions-about-t-sql-transaction-isolation-levels-you-were-too-shy-to-ask/),我有一个问题,根据:
"SERIALIZABLE:当前事务中的查询不能读取另一个尚未提交的事务修改的数据。在当前事务完成之前,没有其他事务可以修改当前事务正在读取的数据,并且没有其他事务可以插入新的行将匹配当前事务中的搜索条件,直到完成。因此,Serializable 隔离级别可以防止脏读、不可重复读和幻读。但是,与其他隔离级别相比,它对性能的影响最大。 "
我对从 1 个会话/查询插入不满足搜索条件的新行感到困惑。示例如下:
假设我有桌子
EmpID FirstName
1 john
2 new employee
3 A new employee
并在单独的选项卡中查询:
--session 1----------------------------------
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
SELECT FirstName FROM EmployeeInfo
WHERE FirstName like 'new empl%'
WAITFOR DELAY '00:00:10'
SELECT FirstName FROM EmployeeInfo
WHERE FirstName like 'new empl%'
ROLLBACK TRANSACTION;
---------session 2---------------------------
begin transaction;
UPDATE EmployeeInfo
SET FirstName = 'frank'
WHERE EmpID = 1;
commit transaction;
-----session 3----
insert into EmployeeInfo values('A new employe 2')
我一个接一个地执行查询:会话 1、会话 2、会话 3。 我预计会话 1 不会停止会话 2 和会话 3 的执行,因为来自该会话的更新和插入不满足第一个查询中使用的搜索条件。但是,在结果中,我可以看到会话 1 必须在会话 2 和会话 3 执行之前完成(回滚)。
但是,虽然我在会话 1 中使用其他搜索条件,如下所示:
--session 1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
SELECT EmpID, FirstName FROM EmployeeInfo
WHERE EmpID = 2
WAITFOR DELAY '00:00:10'
SELECT FirstName FROM EmployeeInfo
ROLLBACK TRANSACTION;
然后,会话 2 和会话 3 独立于会话 1 完成。 这是为什么?为什么喜欢条件块插入而“=”不插入?
编辑: 1. EmpID 上只有一个主键。
【问题讨论】:
-
包含索引的表的定义是什么?
标签: sql-server database isolation-level