首页 > 代码库 > 数据库隔离级别深入理解(ORACLE)

数据库隔离级别深入理解(ORACLE)

  

  TRANSACTION_READ_UNCOMMITTED 1

  这种隔离级别最低,脏读,不可重复读,幻读都会发生,我用的oracle,并没有支持这个级别,不作研究。

  TRANSACTION_READ_COMMITTED  2 

  This is the default transaction isolation level. Each query executed by a transaction sees only data that was committed before the query (not the transaction) began. An Oracle query never reads dirty (uncommitted) data.

  Because Oracle does not prevent other transactions from modifying the data read by a query, that data can be changed by other transactions between two executions of the query. Thus, a transaction that runs a given query twice can experience both nonrepeatable read and phantoms.

  可以避免脏读,当前connection读到的都是其他connection已经commit的数据。orcale的默认级别。

  TRANSACTION_REPEATABLE_READ 4

  这是避免不可重复读的隔离策略,oracle也不支持这个,我们可以用sql语句select..... for update 来理解,就是查询操作都要把你要查询的行加锁。这样别人就不能改了,这样也就不会发生不可重复读了。

  我做了个实验用一个connection读一个字段,然后将线程等待5秒,然后再读同样的东西,在等待5秒过程中,用另一个线程去update并提交了这个字段,结果第一个线程读取得到的两个值一个是改之前的一个是改之后的,我把conn的隔离级别设成4,就报oracle不支持的错了。所以可想而知如果oracle支持,那么这两次读取应该是一致的。

  TRANSACTION_SERIALIZABLE 8

  最高的级别,所有问题都不会发生。我用的oracle11,做实验发现开了这个隔离级别后,是能保证不发生幻读了,我用一个线程前后读两次表进行全表查询,另一个线程在中间插入一条记录,第一个线程前后两次结果都一致,然后不开这个隔离级别,后面的结果就变了,说明确实幻读是解决了。但我以为是要将表全部锁住来不让幻读发生,结果却是又能插入新的数据(之后又测试了下删除和修改操作都是可以的,不会被锁),而两次查询前后又都一致,oracle是如何实现的呢:

  Serializable transactions see only those changes that were committed at the time the transaction began, plus those changes made by the transaction itself through INSERT , UPDATE , and DELETE statements. Serializable transactions do not experience nonrepeatable reads or phantoms.

  官方的说法是只能查看到在事务开始之前所有被提交的数据,以及自身修改的数据,所有不会发生所有并发产生的读问题。要具体知道里面是怎么实现,还得深入学习oralce的运行原理,有好多知识点比如,undo,redo,sga,日志,scn,LGWR等,现在先知道是什么,以后有时间了静下来好好学习下Oracle,在弄明白How。

读一致性实现原理 

   查询语句进入执行状态时,ORACLE会为它分配一个当前的SCN。该查询语句在数据缓冲区中搜索所需的数据块时,只会读取SCN小于或等于该SCN的数据块。如果所需的数据块的SCN大于该SCN,则该查询语句就会从撤销段中获得对应的数据块的原始版本,并且该版本的SCN同样需要小于或等于该SCN,这样通过对数据块SCN的比较,该查询语句就只会返回在它开始之前就语句提交的数据。保证了不会读取到未提交事务所产生的脏数据块,也不会读取到该查询语句开始执行之后才提交的数据块。

  

----------------

不知道其他数据库如何,oralce支持的这两种隔离级别都是个写锁,在update但未commit的时候,都是把你要操作的那些数据是锁了的,其他人这个时候是不能写这些数据的。也许这和隔离级别没关系了,因为隔离级别正确的理解是从自己出发,我自己能看到什么,而不是关心别人怎么看到我写的。这样想思路就不会绞了。