更新游标

更新游标是一种特殊类型的游标,当行可能被潜在更新时,应用程序会用到它。 更新游标使用可提升的锁定,在其中,数据库服务器在应用程序访存行时对该行放置一个更新锁定。应用程序使用更新游标和 UPDATE...WHERE CURRENT OF 来更新该行时,锁定将更改为互斥锁定。

更新锁定位于应用程序访存的行上时,其他用户仍然可以查看该行。

在某些情况下,数据库服务器可能会对已检查但实际上尚未取得的行加上锁定。 是否发生此类行为取决于数据库服务器如何执行 SQL 语句。

更新游标的优点是,您可以放心地查看某行,不用担心其他用户会在您查看的时候,以及在您更新该行之前对改行进行更改或使用更新游标查看该行。

如果不更新该行,那么在您执行下一个 FETCH 语句或者关闭游标时,数据库服务器的缺省行为是释放更新锁定。然而,如果执行带有 RETAIN® UPDATE LOCKS 子句的 SET ISOLATION 语句,那么在事务结束之前,数据库服务器都不会释放任何当前存在的或后续加上的更新锁定。

图 1 中的代码显示出数据库服务器何时使用游标放置和释放更新锁定。在 fetch row 1 处,数据库服务器为第 1 行添加更新锁定。在 fetch row 2 处,该服务器释放第 1 行的更新锁定并为第 2 行添加更新锁定。然而,在数据库服务器执行带 RETAIN UPDATE LOCKS 子句的 SET ISOLATION 语句后,它不会释放任何更新锁定,直到事务结束为止。在 fetch row 3 处,它对第 3 行放置更新锁定。在 fetch row 4 处,它对第 4 行放置更新锁定。在 commit work 处,服务器释放第 2、3 和 4 行的更新锁定。

图: 释放更新锁定时

declare update cursor
begin work
open the cursor
fetch row 1
fetch row 2
SET ISOLATION TO COMMITTED READ
        RETAIN UPDATE LOCKS
fetch row 3
fetch row 4
commit work

在符合 ANSI 标准的数据库中,通常不需要更新 游标,因为任何选择游标的作用与不带 RETAIN UPDATE LOCKS 子句的更新游标的作用是一样的。

图 2 中的代码显示了数据库服务器将更新锁定提升为互斥锁定。 在 fetch the row 处,服务器对正在访存的行放置更新锁定。在 update the row 处,服务器将该锁提升为互斥锁定。在 commit work 处,它释放该锁。

图: 提升更新锁定时

declare update cursor
begin work
open the cursor
fetch the row
do work
update the row (use WHERE CURRENT OF)
commit work
要使用更新游标,请在应用程序中运行 SELECT FOR UPDATE。