IBM DB2 with cs;
各位好,
在DB2里,一段select 的 sql 后面加上with cs; 是什么意思啊?
[解决办法]
DB2的四种隔离级
1 读可靠性(RS-Read Stability)
如果使用这种隔离级,在一个事务中所有被读取过的行上都会被加上NS锁,直到该事务被提交或回滚,行上的锁才会被释放。这样可以保证在一个事务中即使多次读取同一行,得到的值不会改变。
但是,如果使用这种隔离级,在一个事务中,如果使用同样的搜索标准重新打开已被处理过的游标,则结果集可能改变。(可能会增加某些行,这些行被称为幻影行(Phantom))。这是因为RS隔离级不能阻止通过插入或更新操作在结果集中加入新行。
个人笔记:
? 根据实际测试情况,RS模式下:查询完毕以后,满足条件的结果集中的记录被锁定,不满足条件的不被锁定。
? 可以对不满足条件的记录更新,也可以插入新的记录。其他人可以查询满足已经锁定的记录,但不可以更新。
2 重复读(RR-Repeat Read)
如果使用这种隔离级,在一个事务中所有被读取过的行上都会被加上S锁,知道该事务被提交或回滚,行上的锁才会被释放。这样可以保证在一个事务中即使多次读取同一行,得到的值不会改变。
另外,在同一事务中如果以同样的搜索标准重新打开已被处理过的游标,得到的结果集不会改变。重复读相对于读可靠性而言,加锁的范围更大。
对于读可靠性,应用程序只对符合要求的所有行加锁,而对于重复读,应用程序将对所有被扫描过的行都加锁。例如,如果一个应用程序对一个表中的 10000行数据进行扫描,最终找到了100条符合搜索条件的结果行。如果该应用程序使用的是读可靠性隔离级,应用程序将只对这符合条件的100行加锁;如果该应用程序使用的是重复读隔离级,应用程序将对被扫描过的10000行都加锁。
个人笔记
? 根据实际测试情况,RR模式下:查询完毕以后,不可以对不满足条件的进行更新,也不可以插入新记录。可能原因是:如果允许别人更新记录或者插入新记录的话,则可能造成原来结果集的破坏,重新读的时候和以前不同。
? select for update with rr/rs 是可以用来实现记录锁。是一种特殊情况。即便是RR,仍然可以对其他记录操作。
3 游标可靠性(CS-Cursor Stability)
如果使用这种隔离级,在一个事务中,结果集中只有正在被读取的那一行(游标指向的行)将被加上NS锁,其他未被处理的行上不被加锁。这种隔离级只能保证正在被处理的行的值不会被其他并发的程序所改变。该隔离级是DB2缺省的隔离级。
个人笔记
仅仅在游标在该行的时候锁定,这是一种非常弱的隔离状态。
4 未提交读(UR-Uncommitted Read)
如果使用这种隔离级,对于只读操作,不加行锁。典型的只读操作包括:
? SELECT语句的结果集只读(比如语句中包括ORDER BY子句);
定义游标是指明起为FOR FETCH ONLY。
该隔离级可以改善应用程序的性能,同时可以最大程度的允许并发。但是,应用程序的数据完整性将受到威胁。如果需要读取未提交的数据,该隔离级是唯一选择。
[解决办法]
http://sugongqing.javaeye.com/blog/428367
2009-07-18
db2隔离级别基础知识
关键字: db2隔离级别基础知识
db2隔离级别基础知识
1. JDBC的数据隔离级别设置:
JDBC隔离级别数据库隔离级别数据访问情况
TRANSACTION_READ_UNCOMMITTED(未提交的读)Uncommitted Readur就是俗称“脏读”(dirty read),在没有提交数据时能够读到已经更新的数据
TRANSACTION_READ_COMMITTED (游标稳定性)Cursor Stabilitycs在一个事务中进行查询时,允许读取提交前的数据,数据提交后,当前查询就可以读取到数据。update数据时候并不锁住表
TRANSACTION_REPEATABLE_READ (读稳定性)Read Stabilityrs在一个事务中进行查询时,不允许读取其他事务update的数据,允许读取到其他事务提交的新增数据
TRANSACTION_SERIALIZABLE (可重复的读)Repeatable Readrr在一个事务中进行查询时,不允许任何对这个查询表的数据修改。
“可重复的读”隔离级别rr
当使用可重复的读隔离级别时,在单个事务执行期间锁定该事务引用的所有行。使用这种隔离级别时,同一事务多次发出的同一个 SELECT 语句将始终产生同一结果;丢失更新、脏读、不可重复的读、幻像都不会发生。
使用可重复的读隔离级别的事务可以多次检索同一行集,并可以对它们执行任意次操作,直到由提交或回滚操作终止事务;不允许其它事务执行插入、更新或删除操作,因为这些操作会在隔离事务存在期间影响正在被使用的行集。为了确保在“可重复的读”隔离级别下运行的事务所访问的数据不会受其它事务的负面影响,所以锁定了该隔离事务所引用的每个行 — 而不是仅锁定被实际检索和/或修改的那些行。因此,如果一个事务扫描了 1000 行但只检索 10 行,则所扫描的 1000 行(而不仅是被检索的 10 行)都会被锁定。
那么在现实环境中这个隔离级别是如何工作的呢?假定您拥有一家大型旅馆,并有一个网站,该网站按“先到先服务”的原则接受客户的房间预订。如果您的旅馆预订应用程序是在“可重复的读”隔离级别下运行的,当客户检索某个日期段内的所有可用房间列表时,您将无法更改那些房间在指定日期范围内的费用,而其他客户也将无法进行或取消将会更改该列表的预订,直到生成该列表的事务终止为止。(对于第一个客户的查询所指定范围之外的任何房间,您都可以更改房价,其他客户也都可以进行或取消房间预订。)
“读稳定性”隔离级别rs
当使用读稳定性隔离级别时,在单个事务执行期间,会锁定该事务所检索的所有行。当使用这种隔离级别时,直到隔离事务终止之前,其它事务不能更改隔离事务读取的所有行。此外,其它事务对其它行所作的更改,在提交之前对于运行在“读稳定性”隔离级别下的事务而言是不可见的。因此,当使用“读稳定性”隔离级别时,在同一事务中多次发出 SELECT 语句可能会产生不同的结果。丢失更新、脏读和不可重复的读都不会发生;但是,有可能出现幻像。
使用“可重复的读”隔离级别时,隔离事务引用的每一行都被锁定;但是,在“读稳定性”隔离级别下,只锁定隔离事务实际检索和/或修改的行。因此,如果一个事务扫描了 1000 行但只检索 10 行,则只有被检索到的 10 行(而不是所扫描的 1000 行)被锁定。
那么,这种隔离级别会如何改变旅馆预订应用程序的工作方式呢?现在,当一个客户检索某个日期段内的所有可用房间列表时,您可以更改旅馆中任何房间的房价,而其他客户也可以取消在第一个客户的查询所指定的日期段内所保留房间的预订。因此,如果在终止提交查询的事务之前再次生成列表,则产生的新列表中有可能包含新的房价或第一次产生列表时不可用的房间。
“游标稳定性”隔离级别cs
当使用游标稳定性隔离级别时,只要隔离事务所用的游标定位在某一行上,就会锁定该游标所引用的这一行。所获取的锁一直有效,直到游标重定位(通常通过调用 FETCH 语句)或隔离事务终止为止。因此,当使用这种隔离级别时,在同一事务中多次发出 SELECT 语句可能会产生不同的结果。丢失更新和脏读不会发生;但有可能出现不可重复的读和幻像。
当使用“游标稳定性”隔离级别的事务通过可更新游标从表中检索行时,在游标定位在该行上时,其它事务不能更新或删除该行。但是,如果被锁定的行本身不是用索引访问的,那么其它事务可以将新的行添加到表,并对位于被锁定行前后的行进行更新和/或删除操作。此外,如果隔离事务修改了它检索到的任何行,那么在隔离事务终止之前,即使在游标不再位于这个被修改的行,其它事务不能更新或删除该行。
其它事务在其它行上进行的更改,在提交之前对于使用“游标稳定性”隔离级别的事务是不可见的。缺省情况下,大多数事务都使用“游标稳定性”隔离级别。
这种隔离级别对旅馆预订应用程序有什么影响呢?现在,当一个客户检索某个日期段内的所有可用房间列表,然后查看关于所产生的列表上每个房间的信息时(每次查看一个房间),您可以更改旅馆中任何房间的房价,而其他客户可以对任何日期段的任何房间进行或取消预订;唯一的例外是第一个客户当前正在查看的房间。当第一个客户查看列表中另一个房间的信息时,对于这个新房间也是一样;您现在可以更改第一个客户刚才查看的房间的房价,其他客户也可以预订该房间,但不能对第一个客户当前正在查看的房间进行这些操作。
“未提交的读”隔离级别ur
在使用未提交的读隔离级别的情况中,当单个事务检索行时,仅当另一个事务试图删除或更改被检索的行所在的表时,才会在单个事务期间锁定这些行。因为在使用这种隔离级别时,行通常保持未锁定状态,所以丢失更新、脏读、不可重复的读和幻像都可能会发生。
在大多数情况下,其它事务对行所作的更改,在提交或回滚之前对于使用“未提交的读”隔离级别的事务是可见的。但是,此类事务不能看见或访问其它事务所创建的表、视图或索引,直到那些事务被提交为止。类似地,如果其它事务删除了现有的表、视图或索引,使用“未提交的读”隔离级别的事务仅当进行删除操作的事务终止时才能了解这一情况。这种行为有一个例外:当运行在“未提交的读”隔离级别下的事务使用可更新游标时,该事务的行为和在“游标稳定性”隔离级别下运行一样,并应用“游标稳定性”隔离级别的约束。
“未提交的读”隔离级别通常用于那些访问只读表的事务和/或某些执行 SELECT 语句的事务,这些语句对其它事务的未提交数据没有负面效果。
那么这种隔离级别对旅馆预订应用程序有什么影响呢?现在,当一个客户检索某个日期段内的所有可用房间列表时,您可以更改旅馆中任何房间的房价,而其它客户也可以对任何日期段内的任何房间进行或取消预订。此外,如果其它客户取消了预订,即使他们还没有终止其事务并将那些取消提交到数据库,所生成的列表就可以包含这些取消预订的房间了。
2. 数据库之间的差异:
1).Oracle通过具有意向锁的多粒度封锁机制进行并发控制,保证数据的一致性。其DML锁(数据锁)分为两个层次(粒度):即表级和行级。通常的DML操作在表级获得的只是意向锁(RS或RX),其真正的封锁粒度还是在行级;DB2也是通过具有意向锁的多粒度封锁机制进行并发控制,保证数据的一致性。其DML锁(数据锁)分为两个层次(粒度):即表级和行级。通常的DML操作在表级获得的只是意向锁(IS,SIX或IX),其真正的封锁粒度也是在行级;另外,在Oracle数据库中,单纯地读数据(SELECT)并不加锁,这些都提高了系统的并发程度,Oracle强调的是能够"读"到数据,并且能够快速的进行数据读取。而DB2的锁强调的是"读一致性",进行读数据(SELECT)时会根据不同的隔离级别(RR,RS,CS)而分别加 S,IS,IS锁,只有在使用UR隔离级别时才不加锁。从而保证不同应用程序和用户读取的数据是一致的。
2). 在支持高并发度的同时,DB2和Oracle对锁的操纵机制有所不同:Oracle利用意向锁及数据行上加锁标志位等设计技巧,减小了Oracle维护行级锁的开销,使其在数据库并发控制方面有着一定的优势。而DB2中对每个锁会在锁的内存(locklist)中申请分配一定字节的内存空间,具体是X锁 64字节内存,S锁32字节内存(注:DB2 V8之前是X锁72字节内存而S锁36字节内存)。
3). Oracle数据库中不存在锁升级,而DB2数据库中当数据库表中行级锁的使用超过locklist*maxlocks会发生锁升级。
4). 在Oracle中当一个session对表进行insert,update,delete时候,另外一个session仍然可以从Orace回滚段或者还原表空间中读取该表的前映象(before image); 而在DB2中当一个session对表进行insert,update,delete时候,另外一个session仍然在读取该表数据时候会处于lock wait状态,除非使用UR隔离级别可以读取第一个session的未提交的值;所以Oracle同一时刻不同的session有读不一致的现象,而 DB2在同一时刻所有的session都是"读一致"的。
5). db2缺省下是使用cs级别,oracle缺省是使用ur
http://hi.baidu.com/pp_qqpp_qq/blog/item/52d37efe1d92be355c600886.html
2007-12-21 01:01
隔离级别分为RR/RS/CS/UR这四个级别。 下面让我们来逐一论述:
1. RR隔离级别: 在此隔离级别下, DB2会锁住所有相关的纪录。 在一个SQL语句执行期间, 所有执行此语句扫描过的纪录都会被加上相应的锁。 具体的锁的类型还是由操作的类型来决定, 如果是读取,则加共享锁; 如果是更新, 则加独占锁。 由于会锁定所有为获得SQL语句的结果而扫描的纪录, 所以锁的数量可能会很庞大, 这个时候, 索引的增加可能会对SQL语句的执行有很大的影响,因为索引会影响SQL语句扫描的纪录数量。
2. RS隔离级别: 此隔离级别的要求比RR隔离级别稍弱,此隔离级别下会锁定所有符合条件的纪录。 不论是读取, 还是更新, 如果SQL语句中包含查询条件, 则会对所有符合条件的纪录加相应的锁。 如果没有条件语句, 也就是对表中的所有记录进行处理,则会对所有的纪录加锁。
3. CS隔离级别: 此隔离级别仅锁住当前处理的纪录。
4. UR隔离级别:此隔离级别下,如果是读取操作,不会出现任何的行级锁。对于非只读的操作,它的锁处理和CS相同。
DB2默认的隔离级别是 CS.即 游标稳定性。
[解决办法]
楼上两位的资料都找的好全呀,佩服。
在select后面,加with,就是显示的指定隔离级别,不使用数据库默认的隔离级别。