SQLServer事务隔离级别
数据库中的事物是具有原子性(Atomicity),一致性(Consistemcy),隔离性(Isolation),持久性(Durability)四个特征。
1、原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。
2、一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序 串行执行的结果相一致。
3、夺隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
4、夺持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。
事务的ACID特性是由关系数据库系统(DBMS)来实现的,DBMS采用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所作的更新,如果某个事务在执行过程中发生错误,就可以根据日志撤销事务对数据库已做的更新,使得数据库同滚到执行事务前的初始状态。 对于事务的隔离性,DBMS是采用锁机制来实现的。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。
一致性和隔离性是通过锁来实现对相同数据的访问隔离的实现。事物的隔离级别又可以影响锁的申请和时间的时机。
不同的事物隔离级别又可以对锁的申请和释放产生不同的影响,在对数据库做事物控制的时候需要了解隔离级别对事物的影响。
事务隔离级别通过影响读操作来间接地影响写操作;可以在回话级别上设置事务隔离级别也可以在查询(表级别)级别上设置事务隔离级别。
SQL Server实现SQL99标准规定的事务的四个隔离级别(未提交读,已提交读,可重复读,序列化)之外,另外增加了两个隔离级别(快照和基于行版本的已提交读隔离级别)。
不同的隔离级别对控制脏读,不可重复读,幻读有一定的控制,也会并发有一定程度的影响,隔离级别越低,并发性越高,但是产生脏读,不可重复读,幻读等可能性越大;随着事物隔离级别的提交,可以控制脏读,不可重复读,以及幻读的现象,但是并发性也会随之降低。事物隔离级别和执行计划都可以影响锁(范围)的申请和释放时机,本文暂不讨论执行计划对锁申请的影响,仅在隔离级别上说明锁的申请和释放。
数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。 隔离级别越高,读操作的请求锁定就越严格,锁的持有时间久越长;所以隔离级别越高,一致性就越高,并发性就越低,同时性能也相对影响越大.
脏读:事务A向表中插入了一条数据,此时事务A还没有提交,此时查询语句能把这条数据查询出来,这种现现象称为脏读;脏读比较好理解
不可重复读:一个事务A第一次读取的结果之后, 另外一个事务B更新了A事务读取的数据,A事务在第二次读取的结果和第一次读取的结果不一样这种现象称为不可重复读
幻读:事务A查询表里面的所有数据,这时事务B向表中插入了一条数据,这时事务A第一次的查询结果和第二次的查询结果不一致,这种现象我称为幻读。
一.第1级别:Read Uncommitted(读取未提交内容) 相当于with(nolock)
(1)所有事务都可以看到其他未提交事务的执行结果;
(2)本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少;
(3)该级别引发的问题是——脏读(Dirty Read):读取到了未提交的数据。
二.第2级别:Read Committed(读取提交内容)
(1)这是大多数数据库系统的默认隔离级别(Oracle和SQLServer默认的);
(2)它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变;
(3)这种隔离级别出现的问题是——不可重复读(Nonrepeatable Read):不可重复读意味着我们在同一个事务中执行完全相同的select语句时可能看到不一样的结果。
导致这种情况的原因可能有:
(1)有一个交叉的事务有新的commit,导致了数据的改变;
(2)一个数据库被多个实例操作时,同一事务的其他实例在该实例处理其间可能会有新的commit。
三.第3级别:Repeatable Read(可重复读)相当于(HOLDLOCK)
(1)这是MySQL的默认事务隔离级别;
(2)它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行;
(3)此级别可能出现的问题——幻读(Phantom Read):当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行;
(4)InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
四.第4级别:Serializable(可序列化)
(1)这是最高的隔离级别;
(2)它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题;简言之,它是在每个读的数据行上加上共享锁;
(3)在这个级别,可能导致大量的超时现象和锁竞争。
五.:Snapshot(快照)
(1)SNAPSHOT 在SNAPSHOT隔离级别下,当读取数据时可以保证操作读取的行是事务开始时可用的最后提交版本
(2)同时SNAPSHOT隔离级别也满足前面的已提交读,可重复读,不幻读;该隔离级别实用的不是共享锁,而是行版本控制
六.Read Committed Snapshot(已提交读快照)
READ COMMITTED SNAPSHOT也是基于行版本控制,但是READ COMMITTED SNAPSHOT的隔离级别是读操作之前的最后已提交版本,而不是事务前的已提交版本,有点类似前面的READ COMMITTED能保证已提交读,但是不能保证可重复读,不能避免幻读,但是又比 READ COMMITTED隔离级别多出了不需要获取共享锁就可以读取数据