<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>

          面試官:說說MySQL的事務(wù)隔離?

          共 2729字,需瀏覽 6分鐘

           ·

          2020-09-15 18:54


          點擊上方「藍字」關(guān)注我們

          數(shù)據(jù)庫的事務(wù)隔離

          前段時間,公司內(nèi)部遇到了一個問題,就是我們創(chuàng)建的同一批任務(wù),別分配給了不同的實例去執(zhí)行,導(dǎo)致線上的結(jié)果出現(xiàn)問題。?另一個組的leader說沒有開啟事務(wù),設(shè)置下事務(wù)就可以。?數(shù)據(jù)庫一出現(xiàn)一致性問題,就說開啟事務(wù),我就有點疑惑,數(shù)據(jù)庫的事務(wù)到底是怎么保證一致性的。

          在看下面的內(nèi)容,我們可以先思考幾個問題。

          ?

          數(shù)據(jù)庫的隔離級別都有什么??數(shù)據(jù)庫的MVVC視圖是怎么實現(xiàn)的??數(shù)據(jù)庫的隔離級別是為了解決什么問題的??看完上面三個問題,自己能回答上來幾個呢?不急。我們繼續(xù)往下看

          ?

          數(shù)據(jù)庫的事務(wù)

          數(shù)據(jù)庫的事務(wù)我們簡單來說就是用來保證數(shù)據(jù)的正確性,它只有兩個操作:事務(wù)要么成功,要么失敗并進行回滾。

          為什么這么做呢?這是因為一般我們進行事務(wù)操作,都會進行一組操作。比如你常見的金融轉(zhuǎn)賬。

          在這個轉(zhuǎn)賬事務(wù)里面包含2個操作:

          • 扣自己銀行賬戶的錢
          • 給對應(yīng)的賬戶添加收到的錢。

          現(xiàn)在思考下,如果我們沒有添加事務(wù),那么會出現(xiàn)什么樣的情況呢?

          1. 如果先扣錢成功,執(zhí)行給別人加錢失敗。而錢已經(jīng)扣了,對方?jīng)]收到錢,你說怎么辦?
          2. 如果先給對方加錢,而扣你錢的時候沒扣成功。這錢銀行給的補助嗎?嘿嘿,那銀行肯定不開心。

          所以了我們只能在這種操作中使用事務(wù),來保證執(zhí)行的成功與失敗,失敗了要進行回滾,保證扣錢的操作也不執(zhí)行。

          事務(wù)的ACID

          事務(wù)具有四個特性,這四個特性簡稱為ACID

          • 原子性Atomicity:同一組操作,要么做,要么不做,一組中的一兩個執(zhí)行成功不代表成功,所有成功才可以。這就是原子性,做或者不做(失敗進行回滾)。
          • 一致性Consistency:數(shù)據(jù)的一致性,就像上面的舉例說的,你扣錢了,對方?jīng)]加錢,那肯定不行。
          • 隔離性Isolation:多個數(shù)據(jù)庫操作同一條數(shù)據(jù)時,不能互相影響。不能你這邊變動,那邊數(shù)據(jù)空間就變換了。
          • 持續(xù)性Durability: 事務(wù)結(jié)果提交后,變動就是永久性的,接下來的操作或者系統(tǒng)故障不能讓這個記錄丟失。

          今天主要說的事務(wù)就是隔離。看看事務(wù)是怎么保證數(shù)據(jù)之間的隔離

          事務(wù)的隔離級別

          不同的事務(wù)隔離級別對應(yīng)的不同的數(shù)據(jù)執(zhí)行效率,隔離的越嚴(yán)格,那么執(zhí)行的效率就越低下,下面的四個隔離級別是原來越嚴(yán)格。

          • 讀未提交(read uncommitted):指數(shù)據(jù)在事務(wù)執(zhí)行時,還沒有提交,其他事務(wù)就可以看到結(jié)果
          • 讀提交(read committed):指數(shù)據(jù)在其事務(wù)提交后,其他事務(wù)才能看到結(jié)果。「視圖是在執(zhí)行sql語句的時候進行創(chuàng)建,具體視圖看下面的數(shù)據(jù)隔離是怎么實現(xiàn)的」
          • 可重復(fù)讀(repeatable read):一個事務(wù)在執(zhí)行過程中,看到的結(jié)果與其啟動的時候看到的內(nèi)容是一致的。啟動的時候會創(chuàng)建一個視圖快照,該事務(wù)狀態(tài)下,會看的一致是這個視圖快照內(nèi)容,其他事務(wù)變更是看不到的。「注意是讀取的過程,如果是更新,那么會采用當(dāng)前讀,就是其他事務(wù)的更新操作會拿到結(jié)果,用來保證數(shù)據(jù)一致性」
          • 串行化(serializable):顧名思義,就是將多個事務(wù)進行串行化(讀寫過程中加鎖,讀寫沖突,讀讀沖突),一個事務(wù)結(jié)束后,另外一個事務(wù)才能執(zhí)行,帶來的效果就是并行化不好,效率低下。

          Mysql中默認(rèn)的事務(wù)隔離級別是可重復(fù)讀,使用下面這個命令進行查看當(dāng)前的事務(wù)級別,

          show?variables?like?'transaction_isolation';

          #?下面的語句進行修改事務(wù)的級別。
          SET?session?TRANSACTION?ISOLATION?LEVEL?Serializable;(參數(shù)可以為:Read uncommitted,Read committed,Repeatable,Serializable)
          事務(wù)級別

          事務(wù)的啟動方式

          在程序中,我們很多時候都是默認(rèn)的自動提交,也就是一個sql操作就是一條事務(wù),但有時候需要的是多個SQL進行組合,我們就要顯式的開啟事務(wù)。

          顯示開啟的語句是用 begin或者 start transaction.同樣在事務(wù)結(jié)束的時候使用commit進行提交,失敗使用rollbakc進行回滾。

          當(dāng)然如果不想讓SQL進行自動提交,我們就將自動提交進行關(guān)閉set autocommit=0,這樣事務(wù)就不會自動提交,需要我們手動的執(zhí)行commit.

          如何避免長事務(wù)

          關(guān)閉自動提交事務(wù)后,就需要我們來自己提交事務(wù),這時候每個語句執(zhí)行都是這樣的。


          begin
          sql語句
          commit

          如果我們在程序編寫中,本來一個sql解決的操作,結(jié)果忘記進行事務(wù)的提交,到下下下一個SQL才進行commit,這樣就會出現(xiàn)長事務(wù)。

          而長事務(wù)往往會造成大量的堵塞與鎖超時的現(xiàn)象,事務(wù)中如果有讀寫(讀讀不沖突,讀寫沖突,寫寫沖突)操作,那么會將數(shù)據(jù)進行鎖住,其他事務(wù)也要進行等待。

          所以在程序中,我們應(yīng)該盡量避免使用大事務(wù),同樣也避免我們寫程序的時候出現(xiàn)偶然的大事務(wù)(失誤?)。

          解決辦法是我們將自動提交打開,當(dāng)需要使用事務(wù)的時候才會「顯示的開啟事務(wù)」

          程序中出現(xiàn)大量的事務(wù)等待怎么辦

          在MySQL中想定位一個長事務(wù)問題還是很方便的。

          首先我們先找到正在執(zhí)行的長事務(wù)是什么。

          select?t.*,to_seconds(now())-to_seconds(t.trx_started)?idle_time?from?INFORMATION_SCHEMA.INNODB_TRX?t?\G

          該語句會展示出事務(wù)的執(zhí)行的開始時間,我們可以很簡單的算出,當(dāng)前事務(wù)執(zhí)行了多久,其中上面的idle_time就是執(zhí)行的事務(wù)時間

          假設(shè)我們現(xiàn)在設(shè)定的超過30s執(zhí)行的事務(wù)都是長事務(wù),可以使用下面語句進行過濾30s以上的長事務(wù)。

          select?*?from?information_schema.innodb_trx?where?TIME_TO_SEC(timediff(now(),trx_started))>30

          通過information_schema.innodb_trx 我們就能定位到長事務(wù)。

          從而決定長事務(wù)是否要被殺死,還是繼續(xù)等待。如果出現(xiàn)死鎖的情況,處理方式也是類似,查找到死鎖的語句,然后進行殺死某個語句的執(zhí)行(「有點暴力」)。

          總結(jié)

          本次只是了解了下事務(wù)的隔離級別以及啟動方式與怎么定位長事務(wù),關(guān)于數(shù)據(jù)隔離的實現(xiàn)放在了下一篇文章中。盡情期待。


          你點的每個在看,我都認(rèn)真當(dāng)成了喜歡
          瀏覽 114
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  大香久久 | 天天操,天天日,天天干 | 一级高清片 | 人人干人人摸人人操 | 青青草视频网 |