乐观锁定
乐观锁定是一项技术,它用于在选择行与更新或删除行之间未拥有行锁定的 SQL 数据库应用程序。
编写应用程序时,乐观地假定在更新或删除操作前未锁定的行不可能更改。 如果行更改,那么更新或删除操作将失败,并且应用程序逻辑将通过重试选择操作(此处是举例说明)来处理这种故障。 乐观锁定的一个优点是提高了并行性,因为其他应用程序可以读写该行。 在业务交易与数据库事务无关的三层环境中,由于不能在业务交易间保持锁定,所以使用乐观锁定技术。
但是,按值乐观锁定具有一些缺点:
- 在没有其他数据服务器支持的情况下可能导致主动错误信息,它是使用乐观锁定时出现的一种情况,表示在选择后已更改的行必须重新选择才能进行更新。 (这与被动错误信息不同,它表示在选择后未更改的行必须重新选择才能进行更新。)
- 在应用程序中需要更多的重试逻辑
- 构建 UPDATE 搜索条件对应用程序来说很复杂
- Db2® 服务器根据值搜索目标行的效率低下
- 某些客户机类型与数据库类型之间的数据类型不匹配(例如,时间戳记)不允许在搜索式 UPDATE 中使用所有列
下列新增的 SQL 函数、表达式和功能支持更容易且速度更快的乐观锁定,这种乐观锁定不会产生主动错误信息:
- 行标识(RID_BIT 或 RID)内置函数
- ROW CHANGE TOKEN 表达式
- 基于时间的更新检测
- 隐式隐藏列
DB2 应用程序可通过构建搜索式 UPDATE 语句启用按值乐观锁定,该语句查找具有与所选值完全相同的值的行。 如果行的列值已更改,那么搜索式 UPDATE 语句将失败。
使用此编程模型的应用程序将从增强的乐观锁定功能中获得好处。 请注意,未使用此编程模型的应用程序不会被视为乐观锁定应用程序,它们将继续和以前一样工作。
- 行标识(RID_BIT 或 RID)内置函数
- 可以在选择列表或谓词语句中使用此内置函数。 在谓词中,例如,WHERE RID_BIT(tab)=?,RID_BIT 等号谓词是作为一种新的直接访问方法来实现的,以便有效地找到行。 以前,这种值“使用值的乐观锁定”是通过将所有选择的列值添加至谓词并依赖于某些独特列组合来仅限定单个行完成的,这是一种效率较低的访问方法。
- ROW CHANGE TOKEN 表达式
- 此新表达式将返回 BIGINT 形式的标记。 标记表示行的修改序列中的一个相对点。 应用程序可以将行的当前 ROW CHANGE TOKEN 值与上次访存行时存储的 ROW CHANGE TOKEN 值进行比较,以确定该行是否已更改。
- 基于时间的更新检测:
- 此功能是使用 RID_BIT() 和 ROW CHANGE TOKEN 添加至 SQL 的。 要支持此功能,需要在表中定义一个新生成的列,以用于存储时间戳记值。 可以使用 ALTER TABLE 语句将此列添加至现有表,或者在创建新表时定义该列。 该列是否存在也会影响乐观锁定的行为,这是因为,如果该列用来将 ROW CHANGE TOKEN 的粒度从页级别提高到行级别,这样可以为乐观锁定应用程序带来极大好处。 此功能还已添加到 Db2 for z/OS®。
- 隐式隐藏列:
- 为了兼容,此功能不要求现有的表和应用程序使用 RID_BIT 和 ROW CHANGE TOKEN 列。 使用隐式列列表时,未外部化隐式隐藏列。 例如:
- 对表执行 SELECT * 不会在结果表中返回隐式隐藏列
- 不使用列列表的 INSERT 语句不期望隐式隐藏列的值,但应将该列定义为允许空值或具有另一个缺省值。
注: 请参阅 Db2 词汇表以获取乐观锁定术语的定义,例如 乐观并行控制, 悲观锁定, ROWID和 更新检测。