欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

DB2在单用户和多用户环境数据并发性的处理机制

程序员文章站 2024-02-01 09:08:34
...

本文旨在向您介绍数据一致性的概念,以及 DB2 在单用户和多用户数据库环境中用来维护数据一致性的各种机制。本教程还将帮助您为应对 DB2 10.1 基础认证考试(考试 610)的第 6 部分而做准备。

正在考虑获得 IBM Certified Database Associate(DB2 10.1 基础认证)?那您就来对了地方。这个 DB2 10.1 基础认证准备系列 旨在介绍参加 DB2 10.1 基础认证考试(考试 610)之前必须了解的所有主题。即使您不打算马上参加认证考试,本系列中提供的信息也可以帮助您了解 DB2 10 for z/OS® 和 DB2 10.1 for Linux®, UNIX®, and Windows® 中的新特性和功能。

您没有看到正在寻找的?您可以查看 DB2 9 基础认证 730 准备系列 中的 DB2 9 。

关于本教程

在 DB2 10.1 基础认证考试(考试 610)中,有 13% 的内容旨在测试您对一些机制(有关 DB2 用来允许多个用户和应用程序在不影响数据一致性的情况下与进行交互的机制)的了解。组成考试的这一部分的问题旨在评估:

  • 您能够识别在给定情况下应该使用的隔离级别。
  • 您能够识别 DB2 锁的特征。
  • 您能够列出可以为其获得锁的对象。
  • 您能够识别影响锁的因素。

本教程旨在介绍数据一致性的概念,以及 DB2 用于在单用户和多用户数据库环境中维护数据一致性的两个重要机制:隔离级别和锁。本教程是由 6 部分组成的系列教程中的第 6 部分,您可以使用本教程来准备 DB2 10.1 基础认证考试(考试 610)。

目标

在本教程中的材料涵盖了 DB2 10.1 基础认证考试(考试 610)的第 6 部分的目标。

在完成本教程之后,您应该能够:

  • 识别影响锁的因素。
  • 列出可以在其上获得锁的对象。
  • 适当地使用 LOCK TABLE 语句。
  • 识别 DB2 锁的特征(在所有平台上共享的常用锁)。
  • 识别在给定情况下应该使用的隔离级别。
  • 知道如何以及何时使用当前已提交 (CC) 的语义。

先决条件

要理解本教程所提供的一些内容,您应该熟悉下列术语:

  • 结构化查询语言 (Structured Query Language, SQL):一种用来在关系数据库中定义对象和操纵数据的标准化语言。
  • 对象:数据库中可以用 SQL 创建或操纵的任何东西(例如,表、视图、索引和包等)。
  • 表:一种逻辑结构,用来将数据表示为有固定列数的无序行的集合。每个列都包含一组值,列中所有的值都具有相同的数据类型。列的定义组成了表结构,而行包含实际的数据。
  • 记录:表中一行的存储表示。
  • 字段:表中一列的存储表示。
  • 值:具体的数据项,位于数据库表中行与列的每个交叉点上。
  • DB2 优化器:SQL 预编译器的一个组件,它通过对几个不同访问计划的执行成本进行建模并选择预计成本最低的计划,为数据操纵语言 (Data Manipulation Language, DML) SQL 语句选择一个访问计划。

系统需求

您不需要 DB2 的副本也可以顺利完成本教程,但是,如果您可以访问一个 DB2 数据库,您就能够测试本教程所展示的一些命令和概念。

您可以从 IBM DB2 Express-C 的一个免费版本。

数据一致性

理解数据一致性

为了理解 DB2 如何尝试在单用户和多用户数据库环境中维护数据一致性,您必须先了解数据一致性是什么。此外,您还必须能够识别让数据库进入不一致状态的事件类型。那么到底什么是数据一致性?回答这个问题的最佳方法是研究示例。

假定某公司拥有多家连锁饭店,公司用一个数据库来跟踪每家饭店中的库存等信息。数据库包含每家连锁饭店的库存表。每当一家饭店收到或用掉一部分货物时,就会更新相应的库存表。现在,假定将一箱咖啡从一家饭店(其咖啡库存量充足)调配到另一家饭店(其咖啡刚刚用完)。为了准确地反映这一次库存调配,在接收方饭店的库存表中所存储的咖啡瓶数的值需要有所增加,而调出方饭店的表中所存储的咖啡瓶数的值需要有所减少。如果用户增加了接收方饭店的库存表中的咖啡瓶数的值,但没有减少调出方饭店库存表中的咖啡瓶数的值,那么数据库中的数据就会不再一致。此时所有连锁店的咖啡的总瓶数不再准确,调出方饭店的咖啡瓶数也不再准确。

在单用户环境中,如果用户没有进行必要的更改(如前面的示例),或者如果在用户或应用程序进行更改的过程中系统崩溃了,又或者如果应用程序过早地终止,那么数据库中的数据都会变得不一致。在多用户环境中,当几个用户或应用程序尝试同时访问相同的数据时,也可能会发生不一致。例如,在刚刚介绍的场景中,如果一个用户查询数据库以获得接收方饭店的咖啡瓶数,同时另一个用户在更新两家饭店的库存表,以反映有一箱咖啡从一家饭店转移到另一家饭店,在更新被提交之前,查询将会错误地显示没有剩余的咖啡。

事务、隔离级别和锁

事务

DB2 用于保持数据一致性的主要机制是事务。事务(也称为工作单元)是一种将一个或多个 SQL 操作组合成一个单元的可恢复序列,通常位于应用程序中。事务的启动和终止定义了数据库内的一致性点;要么将一个事务中执行的所有操作的结果都应用于数据库,并使其成为永久性的(已提交),要么完全撤消(已回滚)它们,并且数据库回到事务启动之前的状态。在单用户环境中,事务是按顺序运行的,并且不必与其他并行运行的事务竞争。但在多用户环境中,事务通常是同时运行的。因此,每个事务都有可能干扰正在运行的任何其他事务;要控制所允许的总干扰数量,就需要使用另一个机制:隔离级别。

有可能彼此干扰的事务被称为是交错的(或并行的)事务,而彼此完全隔离的事务被称为是可序列化的 事务,这意味着,同时运行它们的结果与按顺序(一个接一个地)运行它们的结果将没有什么不同。在理想的情况下,每个事务都应该是可序列化的。为什么呢?假设一个销售人员和会计师在同一时间使用相同的数据库。现在,假设销售人员在录入 X 公司的订单(以生成报价),但没有提交其录入条目。同时,会计师将查询数据库,获得所有未支付订单的列表,检索 X 公司的新订单,并生成一个账单。现在,假设负责 X 公司的销售人员决定不下订单。因为订单还没有发出,所以该销售人员可以回滚事务,有关订单的信息会从数据库中删除。然而,一个星期后,X 公司收到的账单中包含这个从未发出的订单。如果销售人员的事务和会计师的事务彼此完全隔离(也就是说,事务是序列化的),这种情况就不会发生。无论是销售人员的事务在会计师的事务开始前完成,还是会计师的事务在销售人员的事务开始之前完成,在这两种情况下,X 公司都不会收到账单。

如果事务不是可序列化的,那么可能出现四种现象:

  • 丢失更新:当两个事务在同一时间读取相同的数据并且都试图更新该数据时,会出现这种情况,导致其中一个更新的损失。例如:事务 1 和事务 2 读取相同行的数据,并根据读出的原始值为该行计算新的值。如果事务 1 用其新值更新行,而事务 2 在之后更新同一行,那么事务 1 所执行的更新操作都将丢失。
  • 脏读 (Dirty Read):当一个事务读取尚未提交的数据时,会出现这种情况。例如:事务 1 修改了一行数据,而事务 2 在提交更改之前读取了已更改的行。如果事务 1 回滚该变更,那么事务 2 将会读取从未真正存在的数据。
  • 不可重复读取 (Nonrepeatable Read):当一个事务读取同一行数据两次,但每次都获得不同的结果时,就会出现这种情况。例如:事务 1 读取一行数据,然后事务 2 修改或删除该行并提交了变更。当事务 1 尝试重新读取该行,它会检索到不同的数据值(如果该行被更新)或发现该行已经不存在(如果该行被删除)。
  • 幻像:当一行数据与某些搜索条件相匹配,但该行在最初不可见时,就会出现这种情况。例如:事务 1 检索一组满足某些搜索条件的行,然后事务 2 插入一个新行,该行与事务 1 的查询的搜索条件相匹配。如果事务 1 再次执行生成原来那一组行的查询,被返回的将是另一组不同的行。(事务 2 所添加的新行现在将被包含在所生成的这组行中。)