暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

了解您的隔离级别以开发正确有效的Db2程序

原创 eternity 2022-10-12
540

您知道Db2提供了一种方法来更改程序或SQL语句获取锁的方式吗?这种方式称为隔离级别,可以将其设置为指定事务或语句的锁定行为。标准SQL定义了四个可以使用set TRANSACTION isolation LEVEL语句设置的隔离级别:

  • 可序列化

  • 可重复读取

  • 已提交读取

  • 读未提交

隔离级别决定程序在运行时实现的页面或行锁定模式。

Db2支持标准隔离级别的变化。Db2在程序执行级别实现页和行锁定,这意味着在程序运行期间根据需要获取所有页或行锁定。根据隔离级别,在程序运行时释放页锁和行锁。

在Db2中,您可以指定以下四个隔离级别:游标稳定性(CS)、可重复读取(RR)、读取稳定性(RS)和未提交读取(UR)。

使用BIND命令的ISOLATION参数,可以设置包或计划的隔离级别。您还可以在SELECT语句上使用WITH参数来设置单个SQL语句的隔离级别。

游标稳定性是SQL标准读提交隔离级别的Db2实现。CS可能是生产应用程序中使用的最常见的DB2隔离级别,因为它在数据完整性和并发性之间提供了良好的折衷。当指定CS时,事务将永远不会读取尚未提交的数据;只能读取提交的数据。如果在BIND时间未指定任何隔离级别,则光标稳定性是当前默认的隔离级别。

可重复读取提供了更高级别的完整性。在RR隔离级别下,所有页面锁都会一直保持,直到COMMIT(或ROLLBACK)释放它们,而在CS中,只读页面锁会在访问另一个页面时立即释放。

当应用程序需要在一次执行程序时访问两次的行的一致性时,或者当应用程序要求使用CS无法实现的数据完整性时,RR页面锁定策略非常有用。

例如,有一个很好的理由使用RR页面锁定,考虑一个报告程序,它扫描一个表以生成详细报告,然后再扫描一次以生成汇总的管理报告。如果程序是使用CS绑定的,则第一次报告的结果可能与第二次的结果不匹配。假设您正在报告项目活动的预计完成日期,第一份报告列出了每个项目和预计完成日期,管理报告只列出竣工日期超过一年的项目。第一份报告表明,两项活动计划进行一年以上,但是,在第一次报告之后但在第二次报告之前,会进行更新。一位经理意识到她低估了项目所需的资源,她调用一项交易,将项目活动的预计完成日期从8个月更改为14个月。第二份报告由同一计划编制,但报告了3项活动。如果程序使用RR隔离级别而不是CS,则不允许在生成第一个报告之后但在生成第二个报告之前进行UPDATE。程序将保持从生成第一个报告时起所持有的锁,更新程序将被锁定,直到释放锁为止。

再举一个例子怎么样?考虑一个计划,该计划旨在寻找有关信息中心和软件支持部门中基本工资超过30000美元的员工的相关信息。在DB2示例表中,部门“C01”是信息中心,部门“E21”是软件支持。

程序将根据以下SELECT语句打开光标:

 SELECT  EMPNO, FIRSTNME, LASTNAME,
            WORKDEPT, SALARY
    FROM    DSN8B10.EMP
    WHERE   WORKDEPT IN ('C01', 'E21')
    AND     SALARY > 30000;
复制

然后,程序开始获取员工行。进一步假设(可能是这样),语句在WORKDEPT列上使用XEMP2索引。执行员工修改的更新程序同时运行。该计划通过将员工从一个部门转移到另一个部门来处理调动,并通过增加工资来实现加薪。

假设您的一名员工Sally Kwan刚从信息中心调到软件支持部门。进一步假设另一名信息中心员工Heather Nicholls获得了10%的加薪。与报表程序同时运行的更新程序实现了这两个修改。

如果报告程序与CS的隔离级别绑定,则在Sally被报告在部门“C01”之后,但在整个报告完成之前,第二个程序可能会将她从“C01“移动到“E21”。因此,她可能会被举报两次:一次是信息中心员工,另一次是软件支持员工。虽然这种情况很少见,但使用光标稳定性的程序可能会出现这种情况。如果程序被绑定为RR,则不会出现此问题。不过,可能不允许更新程序与报告程序同时运行,因为它会遇到太多锁定问题。

现在想想希瑟的困境。加薪使她的工资增加了10%,从28420美元增加到31262美元。她的工资现在符合SQL语句的WHERE条件中指定的参数。她会被举报吗?这取决于更新是在索引扫描检索行之前还是之后发生的,这显然是一种脆弱的情况。RR再次避免了这个问题。

您可能会想,“如果CS有可能导致如此多的问题,为什么它被如此广泛地使用?为什么不以CS的性能和并发性收益换取RR的完整性?”

答案很简单:列出的问题类型很少。然而,就并发性而言,使用RR的费用可能很大。因此,RR的并发开销和CS的效率之间的权衡通常是不合理的。

Db2提供的第三个隔离级别是读取稳定性(RS)。读取稳定性在功能上与RR隔离级别相似,但稍有不同。检索到的行或页被锁定,直到工作单元结束;在工作单元完成之前,没有其他程序可以修改数据,但其他进程可以插入应用程序在第二次访问行时可能读取的值。

当您的程序可以在每次发出游标或单例SELECT时检索不同的行集时,请考虑对可重复只读使用读取稳定性。如果使用读取稳定性,请确保应用程序不依赖于每次返回的行数相同。

最后,我们讨论最后一个也是最受诟病的隔离级别,未提交读取(UR)。UR隔离级别提供通读锁,也称为脏读或未提交读。使用UR可以帮助克服并发问题。当您使用未提交的读取时,应用程序可以读取已更改但尚未提交的数据。

UR也可以提高性能,因为使用UR隔离级别绑定的应用程序将读取数据,而无需使用锁。这样,应用程序可以在操作表时读取表中包含的数据。考虑以下事件顺序:

  • 1.要更改特定值,请在上午9:00执行包含

执行以下SQL:

UPDATE DSN8B10.EMP
   SET FIRSTNME = ˈMICHELLEˈ
WHERE  EMPNO = 10020;
复制

该事务是一个长时间运行的事务,在不发出COMMIT的情况下继续执行。

  • 2.上午9:01,第二个事务尝试选择
changed, but not committed.
复制

如果第二个事务使用UR隔离级别,那么即使尚未提交,它也会读取更改的数据。显然,如果程序不需要等待获取锁,而只需要读取当时处于任何状态的数据,那么程序的执行速度将比必须等待获取锁和释放资源才能处理的程序快。

然而,在实施之前,必须仔细检查读取未提交数据的含义。可能会出现几种类型的问题。使用前一个示例,如果长时间运行的事务将UPDATE回滚到EMPNO 10020,则使用脏读的程序可能选取了错误的名称(“MICHELLE”),因为它从未提交到数据库。

不准确的数据值并不是使用UR会导致的唯一问题。脏读取可能会导致在不存在重复行的情况下返回重复行。或者,当一个(或多个)实际存在时,脏读取可能导致不返回任何行。此外,如果使用UR隔离级别,ORDER BY子句不能保证行将按顺序返回。显然,在使用UR隔离级别之前必须考虑这些问题。

还要记住,UR隔离级别适用于只读操作:SELECT、SELECT INTO和只读结果表中的FETCH。任何绑定了UR隔离级别的应用程序计划或包都将对任何只读SQL使用未提交读取功能。包含在同一计划或包中且非只读的操作将使用CS隔离级别。

何时使用UR隔离合适?一般经验法则是,当结果必须100%准确时,应避免UR。以下是这种情况发生的示例:

  • 正在对选定数据执行必须平衡的计算

  • 正在从一个源检索数据以插入或更新另一个源

  • 正在执行的生产、任务关键型工作不能包含或导致数据完整性问题

通常,大多数生产Db2应用程序都不是严重的脏读候选程序。然而,在一些特定情况下,脏读功能将是主要的好处。考虑以下情况,证明UR隔离级别是有用的:

  • 需要访问本质上是静态的引用、代码或查找表。由于数据的非易失性,脏读取与大多数情况下的正常读取没有区别。在这些情况下,当代码数据被修改时,任何读取数据的应用程序都会产生最小的问题(如果有的话)。

  • 必须对大量数据进行统计处理。例如,您的公司可能希望确定某个薪酬范围内女性员工的平均年龄。未提交读取平均对多行的影响将是最小的,因为更改单个值不会对结果产生很大影响。

  • 在使用DB2作为DBMS的数据仓库环境中,脏读是非常宝贵的。数据仓库是一种时间敏感、面向主题的业务数据存储,用于在线分析处理。除了定期数据传播和/或复制之外,对数据仓库的访问是只读的。由于数据通常不会更改,因此未提交的读取在只读环境中是完美的,因为它几乎不会造成损坏。世界各地的公司正在实施更多的数据仓库项目,具有脏读功能的DB2是实现数据仓库的明智选择。

  • 在极少数情况下,当一个表或一组表仅由单个用户使用时,UR很有意义。如果只有一个人可以修改数据,那么可以对应用程序进行编码,以便使用UR隔离级别完成所有(或大多数)读取,并且数据仍然是准确的。

  • 最后,如果正在访问的数据不一致,那么使用脏读来访问信息几乎不会造成什么危害。尽管脏读功能可以缓解并发问题并在特定情况下提供更快的性能,但它也可能导致数据完整性问题和不准确的结果。在直接在生产应用程序中实现UR隔离级别之前,一定要了解UR隔离等级的含义及其可能导致的问题。

总结

对于Db2 DBA和应用程序程序员来说,了解四个隔离级别及其对SQL的影响是很重要的。使用隔离级别是控制Db2应用程序的并发性和锁定的有效方法。

原文标题:Know Your Isolation Levels to Develop Correct and Efficient Db2 Programs
原文作者:Craig Mullins
原文链接:https://planetmainframe.com/2022/09/know-your-isolation-levels-to-develop-correct-and-efficient-db2-programs/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论