<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          事務的本質(zhì)和死鎖的原理

          共 2080字,需瀏覽 5分鐘

           ·

          2020-09-18 15:10

          本文來自讀者投稿?

          作者:依波拉?

          原文:https://www.cnblogs.com/klarck/p/13630990.html


          僅以MySQL和Spring為例,本文不介紹事務和鎖的概念。

          本文使用偽代碼表示方法代碼,僅僅表達方法的意義及事務注解。


          事務的形狀


          在我心中,事務一直是這個樣子的



          x軸是上鎖的資源,y軸是消耗的時間,

          事務方塊隨著時間的流逝向下移動,

          當碰觸x軸時資源加鎖,越過x軸時資源解鎖

          上圖是對于方法a的事務形狀,我起名【 事務方塊】。

          @Transactionalfunction a(){    對A表修改,耗時五秒}

          ? 一、多事務



          當一個方法調(diào)用多個被事務注解的子方法時情況是



          上圖是對于方法abc調(diào)用時,a方法、b方法、c方法的事務形狀

          function abc(){    this.a(){}    this.c(){}}@Transactionalfunction a(){    對A表修改,耗時五秒}@Transactionalfunction b(){    對B表修改,耗時五秒}@Transactionalfunction c(){    對C表修改,耗時五秒}


          其中abc方法開始執(zhí)行時,執(zhí)行到a方法,鎖定a表,當a方法結(jié)束b方法開始時,a表解鎖,b表鎖定,當b方法結(jié)束c方法開始時,b表解鎖c表鎖定。

          相當于下圖的三個事務方塊聯(lián)合且相對位置鎖定一起下落,總運行時間15秒



          如果并發(fā)請求兩次abc方法則事務方塊如下圖



          其中a表會先被請求1鎖定5秒后解鎖,再被請求2鎖定5秒,

          其中b表也會先被請求1鎖定5秒后解鎖,再被請求2鎖定5秒,

          其中c表也會先被請求1鎖定5秒后解鎖,再被請求2鎖定5秒,

          而請求1在解鎖表a后緊接著又鎖定了表b五秒,同時表a再被請求2鎖定5秒

          依次類推,請求2都在請求1解鎖對應的表之后,鎖定該表,

          那么總運行時間20秒。


          ? 二、大事務

          @Transactionalfunction abc(){    this.a(){}    this.b(){}    this.c(){}}function a(){    對A表修改,耗時五秒}function b(){    對B表修改,耗時五秒}function c(){    對C表修改,耗時五秒}

          其中abc方法上有事務注解,而子方法a、b、c上沒有事務注解,事務方塊形狀如下圖



          a、b、c三個顏色的方塊是結(jié)合在一起的只能一起執(zhí)行,那么a表被鎖定15秒,b表被鎖定10秒,c表被鎖定5秒

          如果也并發(fā)請求兩次abc方法則總耗時30秒,顯而易見事務方塊越大,耗時越長。


          在這個abc方法中,事務鎖定表是懶鎖定的方式,就是說

          當abc中a方法開始執(zhí)行時,只鎖定了a表,執(zhí)行完a方法后,

          開始執(zhí)行b方法鎖定b表,此時a表不解鎖,當b方法執(zhí)行完后,

          開始執(zhí)行c方法鎖定c表,此時a、b兩個表都不解鎖,當c方法執(zhí)行完后,a、b、c三個表一起解鎖。

          這就造成了以下情況。

          ? 三、死鎖


          有如下兩個方法ab和ba

          @Transactionalfunction ab(){    this.a(){}    this.b(){}}@Transactionalfunction ba(){    this.b(){}    this.a(){}}

          當ab和ba方法同時被執(zhí)行時,事務方塊類似下圖,但不完全



          當ab和ba方法同時被執(zhí)行時,ab鎖定a表,ba鎖定b表,

          當ab執(zhí)行完a方法請求鎖定b表時,ba也執(zhí)行完了b方法請求鎖定a表,

          但ab沒有解開對a表的鎖定,ba也沒有解開對b表的鎖定,那么相互等待對方解鎖,這就是死鎖。


          所以減少死鎖出現(xiàn)的幾率的辦法是減小事務方塊的大小,即減小事務方塊消耗的時間或減小事務方塊鎖定的資源【表或行】

          所以行級鎖不易出現(xiàn)死鎖,表級鎖易出現(xiàn)死鎖,是因為行級鎖事務方塊小,但消耗時間不一定,還是需要參考事務消耗時間。

          如果主鍵是int類型自增id,則相當于把事務可鎖定資源從一個表分成了21億份的行,可見使用行級鎖時事務方塊明顯變小。


          ? 四、名稱來歷


          事務方塊的名字來歷是因為聯(lián)想到俄羅斯方塊,俄羅斯方塊是為了給方塊找一個位置放置,而事務方塊是為了給方塊找一個時間間隙執(zhí)行通過,兩者目的不同。


          很抱歉我不會做動圖,請自行聯(lián)想俄羅斯方塊下落的情況。


          也可以類比成要過橋的車輛,橋?qū)挾裙潭ǎ械能囌加靡卉嚨溃械能囌加脙绍嚨溃械能囌加冒胲嚨溃?/p>

          車的形狀多種多樣,如老式武裝三輪摩托車像ab方法的小車,大客車就是一車道的長車,自行車是半車道的小車。類似的情形很多,可自行聯(lián)想。


          推薦閱讀


          (點擊標題可跳轉(zhuǎn)閱讀)

          MySQL8.0大表秒加字段,是真的嗎?

          MySQL參數(shù)是啥,你知道嗎?

          MySQL redo與undo日志解析

          - End -

          動動手指轉(zhuǎn)發(fā)、在看
          是對我最大的鼓勵

          瀏覽 41
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品久久乐 | 18禁网站国产 | 黄片小视频免费看 | 亚洲乱伦黄色小说视频网址 | 狠狠操B 麻豆传媒肏逼视频 |