Oracle并发与多版本控制
1.什么是并发 |
2.事务隔离级别 2.1 READ UNCOMMITTED 2.2 READ COMMITTED 2.3 REPETABLE READ 2.4 SERIALIZABLE 2.5 READ ONLY |
3.多版本读一致性含义 |
4.写一致性 |
1.多版本控制是指,Oracle能同时物化多个版本的数据,这也是Oracle提供读一致性的基础。
2.事务隔离级别
不同隔离级别可能允许或不允许的3种现象:
脏读(dirty read) 你能读取未提交的数据 |
不可重复读(nonrepeatable read) T1和T2时间读取某一行的结果不一样。 |
幻读(phantom read) T1执行查询,T2再执行这个查询,可能增加了一些行。 不可重复读和幻影读区别在于,幻读中,已经读取的数据没有变化,T2比T1有更多的数据满足你的查询条件。 |
隔离级别 | 脏读 | 不可重复读 | 幻读 |
READ UNCOMMITTED | √ | √ | √ |
READ COMMITTED | × | √ | √ |
REPETABLE READ | × | × | √ |
SERIALIZABLE READ | × | × | × |
行 | 账号 | 账户余额 |
1 | 123 | $500 |
2 | 456 | $240.25 |
…. | ||
342 023 | 987 | $100 |
select sum(acount_balance) from accounts;
在查询中的某个时刻将$400从123转入987,未提交
不同隔离级别,非Oracle数据库和Oracle数据库的表现
非Oracle | Oracle | |
READ UNCOMMITTED | 先计算一次123账号的$400,(在读123到987期间,发生了转账),读到987的时候,又计算一次$400,发生了重复计算。 脏读了 | 会从回滚段读987账号旧版本的$100 |
READ COMMITTED | 更新987的时候,对这一行加了排他锁。读到这一行的时候,必须等待提交或回滚完成,才能继续读下去,而等来的结果仍然可能是错误的(如果提交,读到的是$400,那么会对$400计算两次)。 数据的写入者阻塞数据的读取者 | 由于使用多版本和读一致性,答案总是一样。都从回滚段去读,并且不会被阻塞。 |
REPETABLE READ 同一个查询相对于某个时间点返回的结果是一致的 1.得到一致的答案 2.避免丢失更新 | 低级的共享锁来实现,共享读锁防止其他会话修改我们已经读取的数据。 上面的例子效果就是,T1时刻开始查询,必须等待查询完成,update才能进行。 数据的读取者会阻塞数据的写入者 数据的读取者和写入者可能而且经常会发生死锁 | 多版本实现提供读一致的答案 Oracle实现读一致性不会带来读写阻塞,也不会导致死锁。Oracle永远不会使用共享读锁。 |
SERIALIZABLE |
不必太糾結于當下,也不必太憂慮未來