共计 1518 个字符,预计需要花费 4 分钟才能阅读完成。
这篇文章主要介绍“怎么写一组会出现死锁的 ABAP 程序”,在日常操作中,相信很多人在怎么写一组会出现死锁的 ABAP 程序问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么写一组会出现死锁的 ABAP 程序”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!
我们先看看如何用 Java 编写一个会出现死锁的程序。
不到 40 行代码就完成任务。为了便于 ABAP 从业人员理解,没有使用 Java 里的 Lambda 表达式,否则代码可以更短。
该程序逻辑如下:
线程 1 持有资源 1,试图持有资源 2;线程 2 持有资源 2,试图持有资源 1;死锁发生;
现在进入 ABAP 部分。
ABAP 帮助文档提到,使用 SELECT SINGLE FOR UPDATE 读取单条记录时,会自动在数据库层面为该条记录设置一把锁 (Exclusive lock,有的中文文档翻译成排他锁)。如果上锁操作会导致死锁发生,则会抛出异常。
于是我们首先创建一个 ABAP 数据库表,插入两条记录:
再开发两个 ABAP 程序 ZLOCK1 和 ZLOCK2,分别按照 Z01, Z02 和 Z02, Z01 的顺序使用 SELECT SINGLE FOR UPDATE 向数据库发起读取请求。
开启两个 SAPGUI 窗口,按照下面的步骤执行这两个程序,即可产生死锁。
(1) 以调试模式单步执行程序 ZLOCK1,成功执行完 SELECT SINGLE FOR UPDATE .. WHERE object_id = Z01 , 意味着此时程序 ZLOCK1 在数据库层面对 Z01 这条记录设置了一把锁。
(2) 切换到另一个 SAPGUI 窗口,执行程序 ZLOCK2, 单步调试执行完语句 SELECT SINGLE FOR UPDATE .. WHERE object_id = Z02,即此时程序 ZLOCK2 在数据库层面对 Z02 成功上锁。
(3) 再回到窗口 1,继续调试程序 ZLOCK1,此时调试器会阻塞,因为 ZLOCK1 试图对 Z02 上锁,而此时程序 ZLOCK2 持有记录 Z02 的锁。程序 ZLOCK1 处于阻塞状态,等待 ZLOCK2 释放对记录 Z02 设置的锁。
(3) 回到窗口 2,继续在调试模式下执行 ZLOCK2 程序第 12 行语句。此时程序 ZLOCK2 试图对记录 Z01 上锁,但该记录已经被程序 ZLOCK1 锁住了,程序 ZLOCK2 只好等待程序 ZLOCK1 释放对记录 Z01 的锁;而程序 ZLOCK1 永远也不可能释放对记录 Z01 上的锁,因为此刻它已经处于阻塞状态了,在等待程序 ZLOCK2 释放对记录 Z02 的锁。
此时 ABAP Kernel 检测到程序 ZLOCK2 发生了死锁,抛出一个运行时异常,结束了 ZLOCK2 的执行。程序 ZLOCK2 持有对记录 Z02 的锁也自动释放了。最后的结果是,程序 ZLOCK1 成功地对记录 Z02 上了锁。
在事务码 ST22 里,我们能观察到这次死锁的详情。
ABAP Kernel 这种检测到死锁发生后,立刻终止程序运行的方式,节省了应用开发人员通过阅读代码去分析死锁的时间。
回到 Jerry 之前的 Java 程序,运行之后两个线程陷入死锁,在控制台上没有打印任何可供排错的信息。然而 JDK 本身提供了方便的检查 Java 应用死锁状态的命令行工具:jstack.
命令行执行 jstack,传入 Java 程序的进程 id,如果该程序发生了死锁,该工具会打印出程序里具体是哪一行代码,在试图对何种资源进行上锁操作时出现的死锁,从而帮助开发人员迅速定位到逻辑上存在缺陷的代码位置。
到此,关于“怎么写一组会出现死锁的 ABAP 程序”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!