对于并发问题我基本可以得到结论了,DB2缺省的隔离级别游标稳定性是比CR(ORACLE的缺省隔离级别)高的隔离级别。由于两者的隔离级别不相同,最好参考INFORMIX这种既有CR也有游标稳定性的数据库的隔离级别就清楚了。
隔离级别高当然导致可能并发性能的下降,就这样简单而已,ORACLE和INFORMIX是提供了一个满足SQL-92标准的东西,可以有比较好的并发性,DB2可能还是考虑原来主要在金融领域的应用,试图增加一些东西提供更强的隔离级别,但是自然并发就下降了。
至于DB2无法保证读一致性,纯属胡说。
当然由于DB2缺省的隔离级别的问题,要提高性能,DB2建议对读也要进行提交
--------------------------------------------------------------------------
数据一致性的“及时性”是个人的看法,主要针对的异构数据库。
muti-transaction,snapshot,MQ等等其实都对异构数据库的数据一致性提出了的及时性的解决方案,因此,在这里应用了“数据一致性的及时性”一词,暂时还没有找到更好的词,呵呵。
http://www.51cmm.com/《Gartner:数据质量低下致许多IT项目失败》
我理解,DB2多NODE模式的存在就是为了适应超大型的应用,而这种应用的“数据一致性”就是NODE需要解决的问题,而不是靠isolation level将nodes分割成为信息孤岛。斑竹提到的2 phase解决方式就是muti-transaction方式。
--------------------------------------------------------------------------
本人做了一个简单的对比,有不当的地方请DX指点
DB2 V8.11与ORACLE 9I RELEASE 2的区别
1
DB2的表中的列只可以添加,不可以删除,改名,并且只有VARCHAR类型的长度可以增加 udb V8.2可以改字段
名称,删除字段,字段类型转换等,但是有时会发生错误
ORACLE的表的列中可以添加,删除,改名,某些字段类型可以相互转换
2
DB2和ORACLE都可以预读
DB2:可以针对每个表空间设定不同的预读大小ALTER TABLESPACE USERSPACE1 PREFETCHSIZE 4;
ORACLE:通过参数修改DB_FILE_MULTIBLOCK_READ_COUNT来指定ORACLE实例的预读大小
3
DB2的页相当于ORACLE的DB BLOCK
DB2表的EXTENT大小是相等的,ORACLE表的EXTENT可以是不等的
4
DB2在建立表空间时可以指定页的大小,ORACLE的主DB BLOCK SIZE在建立数据库时确定以后不可以更改,但
是可以修改参数DB_N_CACHE_SIZE,然后建立从块大小的表空间
5
DB2可以建立系统管理和数据库管理的表空间,系统管理表空间可以自动扩展,但数据库管理表空间不能自
动扩展
ORACLE可以建立字典管理和本地管理的表空间都可以自动扩展
6
DB2只有一种被表空间使用的缓冲池可以被手工创建并且可以创建多个,一个表空间只能选用一个缓冲池,D
B2也有日志缓冲等其它缓冲池但不可以人为创建或手工设定,ORACLE有多种类型的缓冲池如日志缓冲池,字
典缓冲池,数据缓冲池,JAVA池,LARGE池都可以通过参数据设定其大小,但是每种缓冲池只有一个
7
DB2的表空间类型有普通类型,大类型,系统临时类型,用户临时类型的表空间
ORACLE的表空间有永久,临时,还原类型的表空间
8
DB2创建表时可以指定CLOB 或BLOB型字段属于某一个大型表空间,索引属于某一个数据库管理的表空间,其
它的列属于一个数据库管理表空间,并且这样的表只能使用数据库管理的表空间,只有数据库管理的表空间
中的表可以跨表空间,表建立以后将不能更改所属表空间,可以更改主索引名称
CONNECT TO XYFDB;
ALTER TABLE ADMINISTRATOR.E DROP PRIMARY KEY ADD CONSTRAINT IDAAA PRIMARY KEY ( A) ;
CONNECT RESET;
ORACLE创建表时可以将多个字段和索引按照值的范围自动的属于多个表空间,但是如果表中有LONG字段将
不支持此表成为分区表,并且ORACLE的表只能含有一个LONG型字段,可以更改所属表空间如
ALTER INDEX "XYF"."IDX_AAAAAA"
REBUILD
PARTITION "A"
TABLESPACE "USERS"
但是不可以更改索引的名称
9
ORACLE有回滚段,ORACLE的回滚依赖回滚段,前滚依赖日志,能够实现读一致性(注意与数据库不同版本特性
WORKSPACE的区别),实现高度的事务隔离,对于大事务要求大的回滚段,回滚段不够大有可能出现快照太旧
的错误,含有活动事务的日志可以被归档,而不会影响数据库的运行.
DB2没有回滚段,前滚回滚都依赖于日志,因此,含有活动事务的日志不可以成为脱机归档日志,如果主日志
写满,就产生附加的日志,如果附加日志有数量限制,达到限制后数据库将会被挂起.个人认为DB2存在读一
致性的问题,UNCOMMIT READ隔离级可以并发读取,但是是脏读,Read Stability隔离级不能做到高度的事务
隔离,Repeatable Read可以实现事务隔离,但是并发性受到限制。
如果有人对ORACLE的读一致性有疑惑可以看一看以下的例子:
下面是几个关于回滚段和死锁的事例:
有表:Test (id number(10)) 有记录1000000条
SQL> create table test (id number(10)) tablespace users;
表已创建。
SQL> begin
2 for i in 1..1000000 loop
3 insert into test values(i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成
一,大SELECT,小UPDATE
A会话----Select * from test;----设scn=101----执行时间09:10:11
B会话-----Update test set id=9999999 where id=1000000----设scn=102-----执行时间09:10:12
我们会发现B会话会在A会话前完成,A会话中显示的ID=100000是从回滚段中读取的,因为A会话在读到ID=1000000所在的BLOCK时发现BLOCK上有事务信息,因此要从回滚段中读,如果UPDATE在SELECT读到此BLOCK之前已经COMMIT,则SELECT 读到此BLOCK时发现其BLOCK上没有事务信息,但是会发现其BLICK的SCN比SELECT自己的SCN大,因此也会从回滚段中读取。因此是否从回滚段读一是看是否有事务信息,二是比较SCN大小。如果B会话在A会话结束前连续多次对同一条记录UPDATE并COMMIT,那么在回滚段中将记录多个“前映像”,而每个“前映像”中不但包括了原BLOCK的数据和SCN也记录了“前前映像”的回滚段地址,因此A会话在查询到被UPDATE过的BLOCK时,会根据BLOCK记录的回滚段的地址,找到回滚段中的“前映像”,发现这个“前映像”的SCN也比自己的大,因此将根据这个“前映像”中记录的“前前映像”的回滚段地址,在回滚段中找到“前前映像”,再与这个“前前映像”比较SCN,如果比自己小就读取,如果还比自己大,则重复以上步骤,直到找到比自己SCN小的“前…前映像”为止,如果找不到,就会报ORA-01555快照太旧这个错误。Oracle回滚段确保了事务的高度的隔离性。即只要回滚段足够大,那么一个SELECT不管执行多长,它读取的所有数据都将是在这条SELECT语句开始执行瞬间这个时间点的值,而不会被其它用户在SELECT读取期间对数据是做过修改而影响。
二、大UPDATE,小SELECT
A会话----Update test set id=1;----设scn=101----执行时间09:10:11
B会话-----select * from test where id=1000000----设scn=102-----执行时间09:10:12
我们会发现B会话会在A会话前完成,B会话中显示的ID=1000000是从BLOCK中直接读取的,因为B会话在读到ID=1000000所在的BLOCK时,A会话还没有来得及对其锁定,因此B会话既不会发现BLOCK上有事务信息,也不会发现BLOCK上的SCN比SELECT的大,因此会从BLOCK中直接读取,如果SELECT在UPDATE锁定此BLOCK后才发出,B会话读到此BLOCK时发现其BLOCK上有事务信息,因此会从回滚段中读取。
三、大UPDATE,小UPDATE
A会话----Update test set id=1;----设scn=101----执行时间09:10:11
B会话1-----Update test set id=999999 where id=1000000----设scn=102-----执行时间09:10:12
B会话2----- select * from test where id=2----设scn=103-----执行时间09:10:14
B会话3----- update test set id=3 where id=2----设scn=104-----执行时间09:10:15
我们会发现B会话1会完成,A会话将一直等待,因为B会话1会先于A会话锁定ID=1000000所在的BLOCK,并改写头部的事务信息,A会话在试图锁定此BLOCK时,发现其上有事务信息,将会一直等待B会话1事务结束后再行锁定, B会话2查询到的ID=2是从回滚段中读取的而不是从BLOCK中直接读出来的。因为A会话已将ID=2的BLOCK锁定,并写入了回滚段,从B会话3可以证明这一点,B会话3发出后,B会话3会收到死锁的信息,死锁的原因是A会话在等待B会话对ID=1000000所在的BLOCK解锁,现在B会话又在等待A会话对ID=2所在的BLOCK解锁,因此形成死锁,因此证明ID=2所在的BLOCK已被A会话锁定,然后A会话也会收到死锁的信息
--------------------------------------------------------------------------
并发性好不好和能否达到读一致性没有关系。
谈了这么多读一致性,也没有给出一个定义?没有定义的概念如何讨论?
ACID,数据库的重要理论之一
http://databases.about.com/od/speci...ucts/a/acid.htm另外,日志只要写满,就可以被归档,日志满数据库不会被挂起,达到日志满的交易会被回滚,可以用参数设定日志满时block新的交易。另外,db2 v8支持无限日志。
--------------------------------------------------------------------------
收起