设为首页 加入收藏

TOP

SQLServer事务隔离级别的选择如何影响锁定机制(二)
2018-06-12 08:43:17 】 浏览:272
Tags:SQLServer 事务 隔离 级别 选择 如何 影响 锁定 机制

间后,第一个查询窗口中的事务被回滚。你将看到第二个查询窗口返回了从未提交给表的数据。

在第一个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GOEXECUTE dbo.db_reset;
GO
BEGINTRANSACTION;UPDATE dbo.IsolationTestsSET ColA ='Z';--Simulate having some intensive processing here with a waitWAITFOR DELAY '00:00:10';ROLLBACK;
GO
SELECT*FROM dbo.IsolationTests;
GO

在第二个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GO-- READ UNCOMMITTED-- Run this in query window 2 while the 1st query is runningSETTRANSACTION ISOLATION LEVEL READ UNCOMMITTED;SELECT*FROM dbo.IsolationTests;

从结果中可以看出,第二个查询立即返回,并返回随后在第一个查询窗口中回滚的值。

读提交

在Read提交的测试中,我们将重新运行这些语句。设置第二个查询窗口以使用已提交的事务隔离级别。因此,在第二个查询窗口中运行的SELECT语句必须等到第一个事务完成(事务被提交或回滚)之后才能读取数据——它被打开的事务阻塞。

在第一个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GOEXECUTE dbo.db_reset;
GO
BEGINTRANSACTION;UPDATE dbo.IsolationTestsSET ColA ='Y';--Simulate having some intensive processing here with a waitWAITFOR DELAY '00:00:10';ROLLBACK;

在第二个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GO-- READ COMMITTED-- Run this in query window 2 while the 1st query is runningSETTRANSACTION ISOLATION LEVEL READ COMMITTED;SELECT*FROM dbo.IsolationTests;

正如你所看到的,查询窗口2中的语句必须等待查询窗口1中的事务在运行之前完成,查询窗口2在查询窗口1完成后返回表中的值。

可重复读取

对于下一个隔离级别,可重复读取,我们将展示如何在这个隔离级别中从一个表中读取数据两次,在读取之间的一段时间内,如何返回相同的数据。在这个隔离级别下,它必须读取所读取的行的完全相同的数据,因此它将阻塞试图更新这些行中的某些行的第二个事务。然后,我们将从可重复读取更改为Read Read,以显示允许更新运行的效果。

在第一个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GOEXECUTE dbo.db_reset;
GO
SETTRANSACTION ISOLATION LEVEL REPEATABLE READ;BEGINTRANSACTION;SELECT*FROM dbo.IsolationTests;WAITFOR DELAY '00:00:10';SELECT*FROM IsolationTests;ROLLBACK;

在第二个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GOUPDATE dbo.IsolationTests SET Col1 = -1;

注意,查询窗口2等待直到查询窗口1完成,因为查询窗口1是可重复读取的。

重新运行步骤1-3:

更改查询窗口1以使用已提交的隔离级别,并运行代码。

在查询窗口2中运行代码。

请注意,查询窗口2立即完成,而在查询窗口1中,第二SELECT语句返回第一个SELECT语句的不同结果。

可串行化的

在刚才执行的可重复读取测试中,我们看到了如何防止对数据的更新。可序列化隔离级别需要进一步的步骤,并且还可以防止插入或删除发生在该表中。为了测试这一点,我们将基本上从可重复读取重新运行测试,我们将将隔离级别更改为可序列化,并尝试执行插入而不是更新。然后,我们将在可重复读取隔离级别运行此测试,说明如何允许插入运行。

在第一个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GOEXECUTE dbo.db_reset;
GO
-- SERIALIZABLE-- Run this in query window 1SETTRANSACTION ISOLATION LEVEL SERIALIZABLE;--SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- what will happen if this is set insteadBEGINTRANSACTION;SELECT*FROM dbo.IsolationTests;WAITFOR DELAY '00:00:10';SELECT*FROM dbo.IsolationTests;ROLLBACK;

在第二个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GOINSERTINTO dbo.IsolationTests(ColA)VALUES('W');

注意,查询窗口2中的插入等待,直到查询窗口1中的事务完成。

重新运行步骤1-3:

更改查询窗口1以使用可重复读取隔离级别,并运行代码。

在查询窗口2中运行代码。

注意,查询窗口2中的插入立即运行,查询窗口1中的第二个SELECT语句返回插入的行。

快照

我们已经看到的读提交/未提交事务级别也有丢失/双读的问题。可重复读取/可串行化隔离级别消除了这个问题,但是在严重阻塞其他事务的情况下这样做。快照隔离级别消除了可序列化隔离级别所执行的所有并发并发副作用,并且在不引入锁定(从而消除阻塞)的情况下另外进行了这种副作用。在这个测试中,我们将首先显示快照隔离级别中没有阻塞,然后显示在使用可序列化隔离级别时如何阻止这些相同的语句。

在第一个查询窗口中,运行这些语句:

USE IsolationLevelTest;
GOEXECUTE dbo.db_reset;
GO
-- SNAPSHOTALTERDATABASE IsolationLevelTest SET ALLOW_SNAPSHOT_ISOLATION ON;
GO-- Run this in query window 1USE IsolationLevelTest;
GOSETTRANSACTION ISOLATION LEVEL SNAPSHOT;BEGINTRANSACTION;SELECT*FROM dbo.IsolationTests;WAITFOR DELAY '00:00:10';SELECT*FROM dbo.IsolationTests;ROLLBACK;

在第二个查询窗口中,运行这些语句:

USE IsolationLe  
		
编程开发网
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇关于redis持久化的几种方式介绍 下一篇mysql优化之mysql查询性能排序分析