数据库提供了四种事务隔离级别
sql server锁的机制
?
?
该隔离级别与二级封锁协议相对应。读数据前加共享锁,读完就释放。假设a事务对正在读取数据data放置了共享锁,那么data不能被其它事务改写,所以当b事务对data进行读取时总和a读取的data数据是一致的,所以避免了脏读。由于在a没有提交之前可以对data进行改写,那么b读取到的某个值可能会在其读取后被a更改从而导致了该值不能被重复取得;或者当b再次用相同的where字句时得到了和前一次不一样数据的结果集,也就是幻像数据。?repeatableread:RepeatableRead对应第三级封锁协议:读前加共享锁,事务完成才释放。(注意msdn原文中的第一句话:在查询中使用的所有数据上放置锁,所以不存在脏读的情况)。假设a事务对读取的所有数据data放置了锁,以阻止其它事务对data的更改,在a没有提交之前,新的并发事务读取到的数据如果存在于data中,那么该数据的状态和a事务中的数据是一致的,从而避免了不可重复的读取。但在a事务没有结束之前,b事务可以插入新记录到data所在的表中,那么其它事务再次用相同的where字句查询时,得到的结果数可能上一次的不一致,也就是幻像数据。它是MySQL的默认隔离级别serializable:在数据表上放置了排他锁,以防止在事务完成之前由其他用户更新行或向数据集中插入行,这是最严格的锁。它防止了脏读、不可重复读取和幻象数据。
以下是对照表:
隔离级别??????????????????????????????????? 脏读???????????? 不可重复读? ? ? ? ? ? 幻读
读未提交(read uncommitted)? 可能??????????? 可能????? ? ? ? ? ? ? ?? 可能?
读已提交(read committed)???? 不可能????????? 可能???????????????????? 可能?
可重复读(repeatable read)??? 不可能????????? 不可能????????????????? 可能?
可串行化(serializable )?????????? 不可能????????? 不可能?????????????????? 不可能?
?
?
数据库提供了四种事务隔离级别, 不同的隔离级别采用不同的锁类开来实现.
在四种隔离级别中, Serializable的级别最高, Read Uncommited级别最低.
大多数数据库的默认隔离级别为: Read Commited,如Sql Server , Oracle.
少数数据库默认的隔离级别为Repeatable Read, 如MySQL InnoDB存储引擎
即使是最低的级别,也不会出现 第一类 丢失 更新问题 .
?
补充 : 基于元数据的 Spring 声明性事务 :
Isolation 属性一共支持五种事务设置,具体介绍如下:
l????????? DEFAULT 使用数据库设置的隔离级别 ( 默认 ) ,由 DBA 默认的设置来决定隔离级别 .
l????????? READ_UNCOMMITTED 会出现脏读、不可重复读、幻读 ( 隔离级别最低,并发性能高 )
l????????? READ_COMMITTED? 会出现不可重复读、幻读问题(锁定正在读取的行)
l????????? REPEATABLE_READ 会出幻读(锁定所读取的所有行)
l????????? SERIALIZABLE 保证所有的情况不会发生(锁表)
不可重复读的重点是修改 :
同样的条件 ,?? 你读取过的数据 ,?? 再次读取出来发现值不一样了
幻读的重点在于新增或者删除
同样的条件 ,?? 第 1 次和第 2 次读出来的记录数不一样