Isolation levels in SQL Server control the way locking works between transactions.
SQL Server 2008 supports the following isolation levels
- Read Uncommitted
- Read Committed (The default)
- Repeatable Read
- Serializable
- Snapshot
Before I run through each of these in detail you may want to create a new database to run the examples, run the following script on the new database to create the sample data.Note : You’ll also want to drop the IsolationTests table and re-run this script before each example to reset the data.
CREATE TABLE IsolationTests
( Id INT IDENTITY,
Col1 INT ,
Col2 INT ,
Col3 INT
) INSERT INTO IsolationTests(Col1,Col2,Col3)
SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3
UNION ALL SELECT 1,2,3
|
Also before we go any further it is important to understand these two terms….
- Dirty Reads – This is when you read uncommitted data, when doing this there is no guarantee that data read will ever be committed meaning the data could well be bad.
- Phantom Reads – This is when data that you are working with has been changed by another transaction since you first read it in. This means subsequent reads of this data in the same transaction could well be different.
Read Uncommitted
This is the lowest isolation level there is. Read uncommitted causes no shared locks to be requested which allows you to read data that is currently being modified in other transactions. It also allows other transactions to modify data that you are reading.
As you can probably imagine this can cause some unexpected results in a variety of different ways. For example data returned by the select could be in a half way state if an update was running in another transaction causing some of your rows to come back with the updated values and some not to.
To see read uncommitted in action lets run Query1 in one tab of Management Studio and then quickly run Query2 in another tab before Query1 completes.
Query1
BEGIN TRAN
UPDATE Tests SET Col1 = 2
--Simulate having some intensive processing here with a wait WAITFOR DELAY '00:00:10'
ROLLBACK |
Query2
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT * FROM IsolationTests
|
Notice that Query2 will not wait for Query1 to finish, also more importantly Query2 returns dirty data. Remember Query1 rolls back all its changes however Query2 has returned the data anyway, this is because it didn’t wait for all the other transactions with exclusive locks on this data it just returned what was there at the time.
There is a syntactic shortcut for querying data using the read uncommitted isolation level by using the NOLOCK table hint. You could change the above Query2 to look like this and it would do the exact same thing.
SELECT * FROM IsolationTests WITH (NOLOCK)
|
Read Committed
This is the default isolation level and means selects will only return committed data. Select statements will issue shared lock requests against data you’re querying this causes you to wait if another transaction already has an exclusive lock on that data. Once you have your shared lock any other transactions trying to modify that data will request an exclusive lock and be made to wait until your Read Committed transaction finishes.
You can see an example of a read transaction waiting for a modify transaction to complete before returning the data by running the following Queries in separate tabs as you did with Read Uncommitted.
Query1
BEGIN TRAN
UPDATE Tests SET Col1 = 2
--Simulate having some intensive processing here with a wait WAITFOR DELAY '00:00:10'
ROLLBACK |
Query2
SELECT * FROM IsolationTests
|
Notice how Query2 waited for the first transaction to complete before returning and also how the data returned is the data we started off with as Query1 did a rollback. The reason no isolation level was specified is because Read Committed is the default isolation level for SQL Server. If you want to check what isolation level you are running under you can run “DBCC useroptions”. Remember isolation levels are Connection/Transaction specific so different queries on the same database are often run under different isolation levels.
Repeatable Read
This is similar to Read Committed but with the additional guarantee that if you issue the same select twice in a transaction you will get the same results both times. It does this by holding on to the shared locks it obtains on the records it reads until the end of the transaction, This means any transactions that try to modify these records are force to wait for the read transaction to complete.
As before run Query1 then while its running run Query2
Query1
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
BEGIN TRAN
SELECT * FROM IsolationTests
WAITFOR DELAY '00:00:10'
SELECT * FROM IsolationTests
ROLLBACK |
Query2
UPDATE IsolationTests SET Col1 = -1
|
Notice that Query1 returns the same data for both selects even though you ran a query to modify the data before the second select ran. This is because the Update query was forced to wait for Query1 to finish due to the exclusive locks that were opened as you specified Repeatable Read.
If you rerun the above Queries but change Query1 to Read Committed you will notice the two selects return different data and that Query2 does not wait for Query1 to finish.
One last thing to know about Repeatable Read is that the data can change between 2 queries if more records are added. Repeatable Read guarantees records queried by a previous select will not be changed or deleted, it does not stop new records being inserted so it is still very possible to get Phantom Reads at this isolation level.
Serializable
This isolation level takes Repeatable Read and adds the guarantee that no new data will be added eradicating the chance of getting Phantom Reads. It does this by placing range locks on the queried data. This causes any other transactions trying to modify or insert data touched on by this transaction to wait until it has finished.
You know the drill by now run these queries side by side…
Query1
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
SELECT * FROM IsolationTests
WAITFOR DELAY '00:00:10'
SELECT * FROM IsolationTests
ROLLBACK |
Query2
INSERT INTO IsolationTests(Col1,Col2,Col3)
VALUES (100,100,100)
|
You’ll see that the insert in Query2 waits for Query1 to complete before it runs eradicating the chance of a phantom read. If you change the isolation level in Query1 to repeatable read, you’ll see the insert no longer gets blocked and the two select statements in Query1 return a different amount of rows.
Snapshot
This provides the same guarantees as serializable. So what’s the difference? Well it’s more in the way it works, using snapshot doesn’t block other Queries from inserting or updating the data touched by the snapshot transaction. Instead it creates it’s own little snapshot of the data being read at that time, if you then read that data again in the same transaction it reads it from its snapshot, This means that even if another transaction has made changes you will always get the same results as you did the first time you read the data.
So on the plus side your not blocking anyone else from modifying the data whilst you run your transaction but…. You’re using extra resources on the SQL Server to allocate each snapshot transaction the additional resources to store the snapshot data which can be quite significant if your transaction is working with a large amount of data.
To use the snapshot isolation level you need to enable it on the database by running the following command
ALTER DATABASE IsolationTests
SET ALLOW_SNAPSHOT_ISOLATION ON
|
If you rerun the examples from serializable but change the isolation level to snapshot you will notice that you still get the same data returned but Query2 no longer waits for Query1 to complete.
Summary
You should now have a good idea how each of the different isolation levels work. You can see how the higher the level you use the less concurrency you are offering and the more blocking you bring to the table. You should always try to use the lowest isolation level you can which is usually read committed.
相关推荐
在介绍和分析数据库事务隔离级别的经典文献《A Critique of ANSI SQL Isolation Levels》中,作者Hal Berenson、Phil Bernstein、Jim Gray、Jim Melton、Elizabeth O’Neil和Patrick O'Neil深入探讨了ANSI SQL-92...
DB - A Critique of ANSI SQL Isolation Levels.pdf ANSI SQL-92 [MS, ANSI] defines Isolation Levels in terms of phenomena: Dirty Reads, Non-Re-peatable Reads, and Phantoms. This document shows that ...
SQL Server 2005 中引入了快照隔离(Snapshot Isolation)机制,该机制可以提供非阻碍、非锁定的读取一致性,解决了传统的读取已提交(Read Committed)事务隔离级别下的争用问题。 快照隔离机制的核心思想是通过行...
SQL Server中的自定义函数是数据库开发中非常重要的组成部分,它们允许开发者创建自定义的逻辑,以便在查询中重用和简化复杂操作。本篇主要关注SQL Server 2008中的三种自定义函数:标量函数、内联表值函数和多语句...
在SQL Server中,事务是确保数据一致性的重要机制,特别是在存储过程中。存储过程是一组预编译的SQL语句,可以在数据库中被多次调用,提高了效率并降低了网络流量。本篇将详细介绍如何在SQL Server存储过程中使用...
不过,我可以根据标题和描述提供的信息,以及对SQL Server 2008和T-SQL语言基础知识的理解,为您构建一份关于Microsoft SQL Server 2008中T-SQL语言基础知识的知识点概要。 Microsoft SQL Server 2008是微软公司...
2. **关键词解释**:SQL Server中包含许多关键字,如SELECT用于查询数据,INSERT用于插入数据,UPDATE用于更新数据,DELETE用于删除数据,JOIN用于合并两个或多个表的数据,WHERE用于设定查询条件,GROUP BY用于数据...
3. **并发控制策略**:SQL Server采用两种并发控制策略:Snapshot Isolation 和 Multiversion Concurrency Control(多版本并发控制)。多版本并发控制允许旧版本的数据在事务结束前保持存在,这样并发事务就可以...
《SQL Server数据库系统概论》课程是针对数据库管理和开发人员设计的,旨在深入理解SQL Server这一强大关系型数据库管理系统的工作原理、特性和使用方法。本课程基于王珊主编的《数据库系统概论》(第4版)教材,该...
### SQL Server 2005 T-SQL增强 #### 富有表现力的数据类型 (Richer Data Types) 在SQL Server 2005中,T-SQL得到了显著增强,其中一个重要方面是引入了新的数据类型。这些数据类型更加丰富且灵活,能够更好地支持...
在处理SQL Server 2005升级时,兼容性级别的检查与调整是至关重要的一个步骤。兼容性级别决定了SQL Server实例支持的特定版本的功能集。从SQL Server 2000升级到SQL Server 2005时,如果不改变兼容性级别,那么新...
在SQL Server中,事务处理是数据库操作的核心组成部分,它确保数据的一致性和完整性。事务是一组逻辑操作,这些操作被视为单个单元,要么全部完成,要么全部回滚,以维护数据库的ACID(原子性、一致性、隔离性和持久...
本教程将深入讲解如何在C#中调用SQL Server的事务,确保数据操作的一致性和完整性。我们将探讨两种不同的方法来实现这一目标。 首先,让我们了解SQL Server事务的基本概念。事务是数据库操作的逻辑单位,它包含一组...
在探讨SQL Server中的阻塞和死锁之前,我们首先需要理解事务的基本特性——ACID特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。 - **原子性**:事务中的所有...
在SQL Server数据库管理系统中,事务和游标是两个非常重要的概念,它们对于数据操作和处理具有深远的影响。本文将深入探讨这两个主题,并解释如何利用它们解决日常数据库管理中遇到的复杂问题。 首先,我们来谈谈...
在SQL Server中,事务管理是数据库操作的核心组成部分,它确保数据的一致性和完整性。这篇博客“事务管理(二)——SQL SERVER的事务管理”可能详细介绍了SQL Server如何处理事务,包括事务的特性、隔离级别以及如何...
SQL Server的事务处理是数据库操作中的关键环节,关系到系统的性能、稳定性和数据一致性。以下是一些关于SQL Server优化事务处理的详细知识点: 1. **事务的隔离级别**:默认的TIL(Read Committed)隔离级别下,...