DB2 9 根底(730 考试)认证指南,第 6 部分: 数据并发性(3)

developerWorks








并发性和间隔级别

当多个用户访问碰面统一数据库时会产生的现象

在单用户情形中,每个事宜都是顺序执行的,而不会遇到与其他事宜的辩论。可是,在多用户情形下,多个事宜可以(而且常日)同时执行。是以每个事宜都有能够与其他正在运转的事宜产生辩论。有能够与其他事宜产生辩论的事宜称为交错的并行的 事宜,而相互间隔的事宜称为串行化 事宜,这意味着同时运转它们的成效与一个接一个继承地运转它们的成效没有区别。在多用户情形下,在运用并行事宜时,会产生四种现象:

  • 损掉更新:这种情形产生在两个事宜读取并考试考试更新统一数据时,此中一个更新会损掉。譬喻:事宜 1 和事宜 2 读取统一行数据,并都凭证所读取的数据较量争论出该行的新值。如果事宜 1 用它的新值更新该行此后,事宜 2 又更新了统一行,则事宜 1 所执行的更新操纵就损掉了。因为诡计 DB2 的体例,DB2 不容许产生此类现象。
  • 脏读:当事宜读取尚未提交的数据时,就会产生这种情形。譬喻:事宜 1 变革了一行数据,而事宜 2 在事宜 1 提交变革之前读取了已变革的行。如果事宜 1 回滚该变革,则事宜 2 就会读取被以为是未曾存在的数据。
  • 不可反复的读:当一个事宜两次读取统一行数据,但每次掉掉不同的数据值时,就会产生这种情形。譬喻:事宜 1 读取了一行数据,而事宜 2 在变革或删除该行后提交了变革。当事宜 1 考试考试再次读取该行时,它会检索到不同的数据值(如果该行已经被更新的话),或发现该行不复存在了(如果该行被删除的话)。
  • 幻像:当最初没有看到某个与搜刮条件婚配的数据行,而在稍后的读操纵中又看到该行时,就会产生这种情形。譬喻:事宜 1 读取满足某个搜刮条件的一组数据行,而事宜 2 拔出了与事宜 1 的搜刮条件婚配的新行。如果事宜 1 再次执行产生原先行集的盘问,就会检索到不同的行集。

维护数据库的对等性和数据完好性,同时又允很多个使用顺序同时访问碰面统一数据,如许的特征称为并发性。DB2 数据库用来考试考试强迫实行并发性的体例之一是颠末运用间隔级别,它决意在第一个事宜访问碰面数据时,如何对其他事宜锁定或间隔该事宜所运用的数据。DB2 运用下列间隔级别来强迫实行并发性:

  • 可反复的读(Repeatable Read)
  • 读波动性(Read Stability)
  • 游标波动性(Cursor Stability)
  • 未提交的读(Uncommitted Read)

可反复的读间隔级别可以灌注扫数现象,可是会大大高涨并发性的水平(可以同时访问碰面统一本钱的事宜数目)。未提交的读间隔级别供应了最大的并发性,可是后三种现象都能够出现。









可反复读间隔级别

可反复读间隔级别是最严酷的间隔级别。在运用它时,一个事宜的影响完全与其他并发事宜间隔:脏读、不可反复的读、幻像都不会产生。当运用可反复的读间隔级别时,在事宜执行时期锁定该事宜以任何体例 援用的扫数行。是以,如果在统一个事宜中发出统一个 SELECT 语句两次或更屡次,那么产生的成效数据集总是雷同的。是以,运用可反复的读间隔级别的事宜可以屡次检索统一行集,并可以对它们执行随便操纵,直到由提交或回滚操纵终了事宜。可是,在事宜存在时期,不容许其他事宜执行会影响这个事宜正在访问碰面的任何行的拔出、更新或删除操纵。为了确保这种举动,锁定该事宜所援用的每一行 —— 而不是仅锁定被理想检索或修正的那些行。是以,如果一个事宜扫描了 1000 行,但只检索 10 行,则所扫描的 1000 行(而不可是被检索的 10 行)都会被锁定。

那么在现本相况中可反复读间隔级别是如何任务的呢?假定您运用 DB2 数据库跟踪旅舍记载,包括房间预订和房价信息,另有一个基于 Web 的使用顺序,它容许主顾按 “先到先就事” 的准绳预订房间。如果旅舍预订使用顺序是在可反复读间隔级别下运转的,当主顾扫描某个日期段内的可用房间列表时,您(旅舍司理)将无法变革那些房间在指定日期范畴内的房价。异常,其他主顾也无法中止或消除将会变革该列表的预订(直到第一个主顾的事宜终了为止)。可是,关于生成第一个主顾的列表时没有读取的任何房间记载,您可以修正房价。异常,其他主顾也可以中止或消除这些房间的预订。图 2 申明晰明晰这种举动。

图 2. 可反复读间隔级别的示例
RR 间隔级别









读波动性间隔级别

读波动性间隔级别没有可反复读间隔级别那么严酷;是以,它没有将事宜与其他并发事宜的成效完全间隔。读波动性间隔级别可以灌注脏读和不可反复的读,可是能够出现幻像。在运用这个间隔级别时,只锁定事宜虚际检索和修正的行。是以,如果一个事宜扫描了 1000 行,但只检索 10 行,则只需被检索的 10 行(而不是所扫描的 1000 行)被锁定。是以,如果在统一个事宜中发出统一个 SELECT 语句两次或更屡次,那么每次产生的成效数据集能够不同。

与可反复读间隔级别一样,在读波动性间隔级别下运转的事宜可以检索一个行集,并可以对它们执行随便操纵,直到事宜终了。在这个事宜存在时期,其他事宜不克不及执行那些会影响这个事宜检索到的行集的更新或删除操纵;可是其他事宜可以执行拔出操纵。如果拔出的行与第一个事宜的盘问的选择条件婚配,那么这些行能够作为幻像呈现在后续产生的成效数据齐集。其他事宜对其他行所做的变革,在提交之前是不可见的。

那么,读波动性间隔级别会如何影响旅舍预订使用顺序的任务体例呢?当一个主顾检索某个日期段内的扫数可用房间列表时,您可以变革这个主顾的列表之外的任何房间的房价。异常,其他主顾可以中止或消除房间预订,如果第一个主顾再次运转异常的盘问,其他主顾的操纵能够会影响他掉掉的可用房间列表。如果第一个主顾再次盘问统一个日期段内的扫数可用房间列表,产生的列表中有能够包括新的房价或第一次产生列表时不可用的房间。图 3 申明晰明晰这种举动。

图 3. 读波动性间隔级别的示例
RS 间隔级别









游标波动性间隔级别

游标波动性间隔级别在间隔事宜成效方面非常宽松。它可以灌注脏读;但有能够出现不可反复的读和幻像。这是因为在大多半情形下,游标波动性间隔级别只锁定事宜声明并掀开的游标此后盾用的行。

当运用游标波动性间隔级别的事宜颠末游标从表中检索行时,其他事宜不克不及更新或删除游标所援用的行。可是,如果被锁定的行自身不是用索引访问碰面的,那么其他事宜可以将新的行添加到表中,以及对被锁定行前后的行中止更新和/或删除操纵。所获取的锁不时有效,直到游标重定位或事宜终了为止。(如果游标重定位,本来行上的锁就被开释,并掉掉游标现在援用的行上的锁。)另外,如果事宜修正了它检索到的任何行,那么在事宜终了之前,其他事宜不克不及更新或删除该行,纵然在游标不再位于被修正的行。与可反复读和读波动性间隔级别一样,其他事宜在其他行上中止的变革,在这些变革提交之前关于运用游标波动性间隔级别的事宜(这是默许的间隔级别)是不可见的。

如果旅舍预订使用顺序在游标波动性间隔级别下运转,那么有什么影响呢?当一个主顾检索某个日期段内扫数可用房间的列表,然后查看关于产生的列表上每个房间的信息时(每次查看一个房间),您可以变革旅舍中任何房间的房价,可是这个主顾此后正在查看的房间除外 (关于指定的日期段)。异常,其他主顾可以对任何房间中止或消除预订,可是这个主顾此后正在查看的房间除外 (关于指定的日期段)。可是,关于第一个主顾此后正在查看的房间记载,您和其他主顾都不克不及中止任何操纵。当第一个主顾查看列表中另一个房间的信息时,您和其他主顾就可以修正他刚才查看的房间记载(如果这个主顾没有预订这个房间的话);但不克不及修正第一个主顾此后正在查看的房间记载。图 4 申明晰明晰这种举动。

图 4. 游标波动性间隔级别的示例
CS 间隔级别









未提交的读间隔级别

未提交的读间隔级别是最不严酷的间隔级别。理想上,在运用这个间隔级别时,仅当另一个事宜试图删除或变革被检索的行所在的表时,才会锁定一个事宜检索的行。因为在运用这种间隔级别时,行常日坚持未锁定状况,以是脏读、不可反复的读和幻像都能够会产生。是以,未提交的读间隔级别常日用于那些访问碰面只读表和视图的事宜,以及某些执行 SELECT 语句的事宜(只需其他事宜的未提交数据对这些语句没有负面成效)。

望文生义,其他事宜对行所做的变革在已经提交之前关于运用未提交的读间隔级别的事宜是可见的。可是,此类事宜不克不及看见或访问碰面其他事宜所创建的表、视图或索引,直到那些事宜被提交为止。雷同地,如果其他事宜删除了现有的表、视图或索引,那么仅当中止删除操纵的事宜终了时,运用未提交的读间隔级别的事宜才力知道这些工具不再存在了。(肯定要留意一点:当运转在未提交的读间隔级别下的事宜运用可更新游标时,该事宜的举动和在游标波动性间隔级别下运转一样,并使用游标波动性间隔级别的束厄狭窄。)

那么未提交的读间隔级别对旅舍预订使用顺序有什么影响呢?现在,当一个主顾检索某个日期段内的扫数可用房间列表时,您可以变革旅舍中任何房间任何日期的房价,而其他主顾也可以对任何房间中止或消除预订,包括第一个主顾此后正在查看的房间记载(关于指定的日期段)。另外,第一个主顾生成的房间列表能够包括其他主顾正在预订(是以理想上不可用)的房间。图 5 申明晰明晰这种举动。

图 5. 未提交的读间隔级别示例
UR 间隔级别









选择精确的间隔级别

运用的间隔级别不但影响数据库对并发性的支持如何,而且影响并发使用顺序的机能。常日,运用的间隔级别越严酷,并发性就越小,某些使用顺序的机能能够会越低,因为它们要等候本钱上的锁被开释。那么,如何决意要运用哪种间隔级别呢?最好的体例是确定哪些现象是不可接收的,然后选择可以灌注这些现象产生的间隔级别:

  • 如果正在执行大型盘问,而且不盼望并发事宜所做的修正招致盘问的屡次运转前去不同的成效,则运用可反复的读间隔级别。
  • 如果盼望在使用顺序之间掉掉肯定的并发性,还盼望限定的行在事宜执行时期坚持波动,则运用读波动性间隔级别。
  • 如果盼望掉掉最大的并发性,同时不盼望盘问看到未提交的数据,则运用游标波动性间隔级别。
  • 如果正在只读的表/视图/数据库上执行盘问,或许并不介意盘问能否前去未提交的数据,则运用未提交的读间隔级别。









指定要运用的间隔级别

只管间隔级别节制事宜级上的举动,但理想上是在使用顺序级指定它们的:

  • 关于嵌入式 SQL 使用顺序,在预编译时或在将使用顺序绑定到数据库(如果运用延迟绑定)时指定间隔级别。在这种情形下,运用 PRECOMPILE 或 BIND 呼吁 的 ISOLATION 选项来设置间隔级别。
  • 关于开放数据库衔接(Open Database Connectivity,ODBC)和调用级接口(Call Level Interface,CLI)使用顺序,间隔级别是在使用顺序运转时颠末调用指定了 SQL_ATTR_TXN_ISOLATION 衔接属性的 SQLSetConnectAttr() 函数中止设置的。(另外,也可以颠末指定 db2cli.ini 设置文件中的 TXNISOLATION 枢纽字的值来设置 ODBC/CLI 使用顺序的间隔级别;可是,这种体例缺乏灵敏,不克不及像第一种体例那样为一个使用顺序中的不同事宜修正间隔级别。)
  • 关于 Java 数据库衔接(Java Database Connectivity,JDBC)和 SQLJ 使用顺序,间隔级别是在使用顺序运转时颠末调用 DB2 的 java.sql 衔接接口中的 setTransactionIsolation() 体例设置的。

当没有运用这些体例显式指定使用顺序的间隔级别时,默许运用游标波动性间隔级别。这个默许设置使用于遵守令行措置顺序(CLP)执行的 DB2 呼吁、SQL 语句和剧本以及嵌入式 SQL、ODBC/CLI、JDBC 和 SQLJ 使用顺序。是以,也可以为从 CLP 执行的操纵(以及转达给 DB2 CLP 中止措置的剧本)指定间隔级别。在这种情形下,间隔级别是颠末在树立数据库衔接之前在 CLP 中执行 CHANGE ISOLATION 呼吁设置的。

在 DB2 UDB 8.1 及更高版本中,可以指定特定盘问所用的间隔级别,体例是在 SELECT SQL 语句中加上 WITH [RR | RS | CS | UR] 子句。运用这个子句的大致 SELECT 语句示譬喻下所示:

 
SELECT * FROM EMPLOYEE WHERE EMPID = '001' WITH RR


如果使用顺序在大多半时辰需求斗劲宽松的间隔级别(以支持最大的并发性),可是关于此中的某些盘问必须灌注某些现象出现,那么这个子句便是副手您完成目标的好体例。




版权声明: 原创作品,容许转载,转载时请务必以超链接情势标明文章 原始来由 、作者信息和本声明。不然将究查法令责任。

posted @ 2011-03-07 00:10  蓝色的天空III  阅读(152)  评论(0编辑  收藏  举报