连接上下文中的游标行为

在另一语句句柄的写冲突下的常规读游标

应用程序可有多个语句句柄同时对同一个表执行读写操作。当一个句柄对该表执行写操作(例如,UPDATE、DELETE 或 INSERT)而另一个句柄也正在执行读或写操作时,将发生冲突。DB2 Everyplace 采用的行为是首先执行读操作并且总是读取最新的数据。它忽略写冲突(不管该写冲突是否在使用索引)。 例如,假定应用程序有两个语句句柄。句柄 #1 用来从表 T 取装行,而句柄 #2 用来从同一个表删除某些行。很可能已由不同的线程创建了每个句柄(例如,在 Java 线程环境中)。

以下是可能的方案:

// Fetch 2 rows from table T
   Statement handle 1: execute "SELECT A FROM T WHERE primary_key < 10"
   Statement handle 1: fetch one row; fetch another row
    // Delete some rows in table T 
   Statement handle 2: prepare "DELETE FROM T WHERE primary_key = ?" 
   Statement handle 2: execute 
    // Continue to fetch one more row from T 
   Statement handle 1: fetch one row 

此时在执行中,语句句柄 #1 将能够继续取装下一行(如果有的话),不管索引是否正被使用。在上面的方案中,因为存在主键而使得索引正被使用。解决方法是 DB2 Everyplace 将尝试使用句柄 #1 的当前位置重新定位其游标位置(在前进之前)。如果当前位置不再存在(例如,该行已被另一语句句柄删除),则游标在取装时仅需前进至下一位置。同样,如果下一位置被另一语句句柄删除,游标可以跳过该“空位”以进至下一位置。

另一语句句柄的写冲突下的可滚动游标

考虑与上一节中类似的示例,但在此示例中读游标将是可滚动游标。如果它是“不敏感”的可滚动游标,这就不是问题,原因是结果集不会按定义更改。如果游标不是“不敏感”的,则采用的行为将与上面描述的常规读游标相似。实际上,发生冲突之后的读游标采用的行为是:根据最新表数据重新计算结果集并维持当前行集的起始位置。 如果当前行已删除,则游标将进至下一行。

以下示例演示使用 CLP 的可滚动游标的实例。假定表 T 有六行:

create table T (a int, b int) 
     create index idx1 on T(a) 
     insert into T values (1, 1) 
     insert into T values (2, 2) 
     insert into T values (3, 1) 
     insert into T values (3, 2) 
     insert into T values (3, 3) 
     insert into T values (4, 4) 

一般来说,可以考虑这样一个示例:应用程序有两个语句句柄,一个用于读取,而另一个用于删除。

Statement handle 1: enable scrollable cursor;
Statement handle 1: execute "SELECT A FROM T WHERE a < 10"
Statement handle 2: prepare "DELETE FROM T WHERE a = ?" 
Statement handle 1: fetchscroll with SQL_FETCH_FIRST
-- get (1, 1) 
Statement handle 1: fetchscroll with SQL_FETCH_NEXT
-- get (2, 2) 
Statement handle 1: fetchscroll with SQL_FETCH_NEXT
-- get (3, 1) 
Statement handle 2: execute
--- suppose delete row (2, 2) 
Statement handle 1: fetchscroll with SQL_FETCH_NEXT  
-- re-compute previous rows, and return (3, 2) 
Statement handle 1: fetchscroll with SQL_FETCH_PRIOR
-- get (3, 1) 
Statement handle 1: fetchscroll with SQL_FETCH_PRIOR
-- get (1, 1)  note that (2, 2) is gone 
Statement handle 1: fetchscroll with SQL_FETCH_ABSOLUTE, offset 2
-- get (3, 1)  note that (2, 2) is gone 
Statement handle 1: fetchscroll with SQL_FETCH_ABSOLUTE, offset 5
-- get (4, 4)

落实和回滚下的游标,包括自动落实方式

不管是事务或是自动落实方式,打开的游标在落实期间将保持打开状态,而在回滚时关闭。

对象相关性

通过语句句柄 H 准备 SQL 语句可能会对特定对象设置某些相关性。例如,通过索引 Idx 从表 T 选择行需要表 T 和索引 Idx 的存在。如果这些对象被另一语句句柄删除(例如,如果索引 Idx 被删除),通过 H 重新执行该语句将强制重新编译 SQL 语句。因此,查询方案可能不同或者可能返回错误。