使用 Cursor Stability 隔离级别
使用 Cursor Stability 选项来在获取的行上放置共享锁,当您获取另一行或关闭该游标时,将其释放。另一进程还可在同一行上放置共享锁,但没有进程可获得排他锁来更改该行中的数据。当程序基于它从该行读取的数据来更新另一表时,这样的行稳定性很重要。
如果您将隔离级别设置为 Cursor Stability,但您未正在使用事务,则 Cursor Stability 的作用就像 Committed Read 隔离级别一样。
使用 Repeatable Read 隔离级别
使用 Repeatable Read 选项来在会话期间选择的每行上放置共享锁。另一进程也可在被选择的行上放置共享锁,但没有其他进程可在您的事务期间修改任何被选择的行,或在您的事务期间插入满足您的查询的搜索条件的行。如果您在事务期间重复该查询,则您重新读取相同的信息。仅当事务提交或回滚时,才释放共享锁。Repeatable Read 是符合 ANSI 的数据库中缺省的隔离级别。
Repeatable Read 隔离级别放置的锁数目最大,持有锁的时间最长。因此,它是最能减少并发的级别。
缺省的隔离级别
当您根据数据库类型创建数据库时,建立特定数据库的缺省的隔离级别。下列列表描述每一数据库类型的缺省的隔离级别。
隔离级别 数据库类型
Dirty Read 在没有日志记录的数据库中的缺省级别
Committed Read 在不符合 ANSI 的日志记录的数据库中的缺省级别
Repeatable Read 在符合 ANSI 的数据库中的缺省级别
直到您发出 SET ISOLATION 语句之前,缺省的级别保持有效。在执行 SET ISOLATION 语句之后,直到下列事件发生之前,新的隔离级别保持有效:
对于不符合 ANSI 的 GBase 8s 数据库,除非您显式地设置 USELASTCOMMITTED 配置参数,否则,对于缺省的隔离级别 LAST COMMITTED 特性无效。SET ENVIRONMENT 语句或 SET ISOLATION 语句可覆盖此缺省值,并为当前的会话启用 LAST COMMITTED。
使用 RETAIN UPDATE LOCKS 选项
当数据库服务器处理 SELECT ... FOR UPDATE 语句时,使用 RETAIN® UPDATE LOCKS 选项来影响它的行为。
在隔离级别设置为 Dirty Read、Committed Read 或 Cursor Stability 的数据库中,数据库服务器在 SELECT ... FOR UPDATE 语句获取的行上放置更新锁。当您开启 RETAIN UPDATE LOCKS 选项时,数据库服务器保持更新锁,直到事务结束为止,而不是在下一随后的 FETCH 时或当关闭游标时才释放它。此选项防止在当前的用户到达事务的结束之前其他用户在更新了的行上放置排他锁。
您可使用此选项来获得相同的锁定效果,但避免 dummy 更新或可重复读隔离级别的开销。
在当前的会话期间的任何时刻,您都可开启或关闭此选项。
您可通过重置隔离级别而不使用 RETAIN UPDATE LOCKS 关键字来关闭该选项,如下例中所示。
BEGIN WORK;
SET ISOLATION TO
COMMITTED READ LAST COMMITTED RETAIN UPDATE LOCKS;
...
COMMIT WORK;
BEGIN WORK;
SET ISOLATION TO COMMITTED READ LAST COMMITTED ;
...
COMMIT WORK;
通过会话环境控制更新锁
禁用 RETAIN UPDATE LOCKS 行为的另一种方法是执行此 SQL 语句:
SET ENVIRONMENT RETAINUPDATELOCKS 'NONE';
通过重置 RETAINUPDATELOCKS 会话环境变量,这为当前的事务,或为同一会话的任意随后的事务禁用 RETAIN UPDATE LOCKS 子句。
SET ENVIRONMENT RETAINUPDATELOCKS 语句还可使得更新锁的保持成为 Committed Read、Cursor Stability 或 Dirty Read 隔离级别,或对于所有这些隔离级别的缺省行为,不论 SET ISOLATION 语句是否包括 RETAIN UPDATE LOCKS 子句。
要获取更多关于更新锁的信息,请参阅 RETAINUPDATELOCKS 环境选项 和 锁定注意事项。
在事务期间关闭选项
在事务已经开始之后,但在提交或回滚事务之前,如果您将 RETAIN® UPDATE LOCKS 选项设置为 OFF,则可能仍存在几个更新锁。
切换到 OFF,该特性不直接地释放任何更新锁。当您关闭此选项时,数据库服务器恢复到三个隔离级别的正常行为。也就是说,通过紧接在前面的 FETCH 语句,FETCH 语句释放放置在行上的更新锁,且关闭了的游标释放在当前行上的更新锁。
不释放稍早的 FETCH 语句放置的更新锁,除非在同一事务之内出现多个更新游标。在此情况下,随后的 FETCH 还可能释放其他游标的较旧的更新锁。