一致和并发是对立的,需要根据应用,选择权宜之计
数据不一致的现象
---事务内单SQL的情况---
1.
脏读-Dirty Read:本事务读取了其它事务尚未提交的修改数据
例子:读了不该读的
1:00 x=1
1:01 A用户 Update x=2(但未commit)
1:02 B用户 Select x --> x=2
合理的情况是x仍然等于1---事务内多SQL的情况(典型的如,先查再改)---2.
不可重复读-Non Repeatable Read
例子1:自相矛盾
1:00 x=1 y=2
1:01 B用户 Select x,y --> x=1 y=2
1:02 A用户 Update x=2; Commit;
1:03 B用户 Select x+y --> x+y=4
首先这个结果从单条SQL的角度看,是没有问题的。但是,如果把B的两次查询看作一个整体(事务),那么合理的情况应该是
x+y仍然等于3
或者B再进行一次事务,得出 x=2 y=2 x+y=4 的结果例子2:更新丢失
1:00 x=1
1:01 B用户 Select x --> x=1
1:02 A用户 Select x --> x=1
1:03 A用户 Update x=2; Commit;
1:04 B用户 Update x=3; Commit;
同样,从单条SQL来讲,没有任何问题。
但是从逻辑的合理性讲,一般的更新操作都是先查再改,换言之
A真正想做的是Update x from 1 to 2
B真正想做的是Update x from 1 to 3
但最终却造成了在B不知情的情况下,把B的初衷改为了Update x from 2 to 33.
幻影读-Phantom Read
例子:读到了未来
1:00 X1=1 X2=2
1:01 B用户 Select Xi --> X1=1 X2=2
1:02 A用户 Insert X3=3; Commit;
1:03 B用户 Select sum(Xi) --> re=6
其实道理和之前的不可重复读相同,只不过是由Insert引起的罢了。
(甚至Delete也会引起类似的问题,但好像学术界并没有对Delete进行讨论)Isolation LevelRead Uncommitted:1,2,3都会发生
Oracle中严格禁止脏读
在SQL Server 7.0中,是可以选择该级别的
Read Committed:发生2,3(Oracle的默认级别)
Repeatable Read:发生3
Serializable:都不发生
Oracle的实现方式Read Committed:默认就实现
Repeatable Read:
1. 悲观锁(select ... for update),影响并发
2. 乐观锁(update where 所有字段都作为条件),不影响并发
Serializable:
alter session set isolation_level=serializable/read only
posted on 2009-12-05 17:45
Jcat 阅读(208)
评论(0) 编辑 收藏 所属分类:
Database