共計 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 小編會繼續努力為大家帶來更多實用的文章!