十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章主要介绍“怎么写一组会出现死锁的ABAP程序”,在日常操作中,相信很多人在怎么写一组会出现死锁的ABAP程序问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么写一组会出现死锁的ABAP程序”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
目前成都创新互联公司已为上千的企业提供了网站建设、域名、虚拟空间、网站运营、企业网站设计、文县网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
我们先看看如何用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程序”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!