首页 > 代码库 > C# 事务的ACID隔离级别
C# 事务的ACID隔离级别
事务的ACID属性如下:
原子性(Atomicity):事务的所有操作是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。原子性消除了系统处理操作子集的可能性。
一致性(Consistency):数据从一种正确状态转换到另一种正确状态。事务在完成时,必须使所有的数据都保持一致。在相关数据库中,所有规则都必 须应用于事务的修改,以保持所有数据的完整性。当事务结束时,所有的内部数据结构都必须是正确的。在存款取款的例子中,逻辑规则是,钱是不能凭空产生或销 毁的,对于每个(收支)条目必须有一个相应的抵衡条目产生,以保证账户是平的。
隔离性(Isolation):由并发事务所作的修改必须与任何其他并发事务所作的修改隔离。查看数据时数据所处的状态,要么是事务修改它之前的状态,要 么是事务修改它之后的状态。简单的理解就是,防止多个并发更新彼此干扰。事务在操作数据时与其他事务操作隔离。隔离性一般是通过加锁的机制来实现的。
持久性(Durability):事务完成之后,它对于系统的影响是永久性的。已提交的更改即使在发生故障时也依然存在。
其中的隔离性,并不总是需要的。有时候处于性能的考虑,可以降低隔离要求。但必须了解改变隔离级别所带来的问题。
如下:
1.脏读取:
脏读又称无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。
解决办法:用锁,锁定要改变的记录
2.不能重复的读取操作:
当数据在T1事务处理中读取,而在T1运行的同时,另一个事务处理T2,修改了T1中读取的数据,此时就会出现不能重复的读取操作,如果数据在T1多次读取,那么结果就会不同。
解决办法:用锁,锁定读取的记录
3.幻影读取:
幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行, 就好象发生了幻觉一样。
解决办法:用锁,范围锁定。
什么是锁?
锁就是防止其他事务访问指定的资源的手段。锁是实现并发控制的主要方法,是多个用户能够同时操纵同一个数据库中的数据而不发生数据不一致现象的重要保障。 一般来说,锁可以防止脏读、不可重复读和幻觉读。
在我们定义隔离时,可以通过IsolationLevel枚举定义隔离级别(TransactionIsolationLevel)。
隔离级别 | 说明 |
ReadUncommitted | 使用ReadUncommitted,事务处理不会相互隔离,使用这个级别,不需要等待其他事务处理释放锁定的记录,可以从其他事务处理中读取未提交的数据--脏读取,这级别仅用于读取临时修改不太重要的记录,例如报表。 |
ReadCommitted | ReadCommitted等待其他事务处理释放对记录的写入锁定,这样就不会出现脏读取操作,这个级别为读取当前的记录设置读取锁定,为写入的数据设置写入锁定,直到事务处理完成,对于要读取的记录,在移动到下一个记录上时,每个记录都是未锁定的,所以可能出现“无法重复的读取操作”。 |
RepeatableRead | RepeatableRead为读取的记录设置锁定,直到事务处理完成为止,这样就避免了不可“无法重复的读取”的问题,但是幻影读取仍可能发生。 |
Serializable | Serializable设置范围锁定,在运行事务处理时,不能向所读取的记录范围内,添加新记录。 |
Unspecified | Unspecified表示,提供程序使用另一个隔离级别通道,它不同于IsolationLevel的枚举值。 |
Snapshot | Snapshot只能用于sql server2005 以后的版本,在复制修改的纪录时,这个级别会减少锁定,这样其他事务处理就可以读取旧数据,不需等待解锁。 |
Chaos | Chaos类似于ReadUncommitted,除了执行与ReadUncommitted 值的操作外,他不能锁定更新的记录。 |
常用的事务处理隔离级别:
隔离级别 | 脏读取 | 不可重复的读取 | 幻影读取 |
ReadUncommitted | Y | Y | Y |
ReadCommitted | N | Y | Y |
RepeatableRead | N | N | Y |
Serializable | N | N | N |
参考网址:http://www.cnblogs.com/zhouqianhua/archive/2011/04/15/2017049.html
C# 事务的ACID隔离级别