一、在不使用MVCC情况下,隔离性、锁之间的关系:
隔离级别 |
并行级别
|
锁实现
|
Seriallizable
|
读读并行
| 表级锁 |
RR
| 读读并行 |
读加共享锁,写加独占锁
|
RC
|
读写并行、读读并行
|
读不加锁,写加独占锁
|
RU
|
写读并行、读写并行、读读并行
| 读不加锁,写不加锁 |
二、Oracle适用MVCC模式后:
1、Oracle没有RR隔离级别,只有serializable和RC级别:其serializable为假串行,自带解决不可重复读特性,但可能存在幻读问题;RC级别可能存在幻读问题,可以通过将数据记录加载到临时对象中解决。
2、Serializable级别中的应用测试:

用户B的事务因为指定了serializable隔离级别,所以虽然在查询费用明细表之前,用户A提交了对费用明细表的更改,但是因为用户A提交的更改是在用户B的事务开始之后才提交的,所以这个更改对用户B的事务不可见。也就是说,用户B的事务开始之后,其它事务提交的更改都不会再影响事务内的查询结果,这样感觉上用户A的事务好像是在用户B的事务结束之后才执行的似的。这本来是非常好的一个特性,极大地提高了并行性,但是也会造成问题。
3、
RC模式下解决“不可重复读”和“幻读”的方法
首先,无论是“不可重现的读取(nonrepeatable read)”还是“幻读(phantom read)”,都是因为程序反复读取数据产生的。所以首先需要做的是,在一个事务里确保只读取数据一次。最好用C#而不是存储过程实现业务逻辑
,这样很容易做到只读取一次,然后把结果存放到IList或IDictionary里。
比较难办的是需要更新数据的情况。
三、悲观锁和乐观锁
悲观锁:依赖数据库隔离级别或for update实现锁
乐观锁:通过版本号自己控制,例如通过版本号方式甚至可以在读未提交情况下,实现写写并行