<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之InnoDB存儲引擎:事務(wù)之基本實踐

          共 3111字,需瀏覽 7分鐘

           ·

          2021-08-31 08:40

          事務(wù)作為數(shù)據(jù)庫的一項重要特性,這里我們簡單介紹下什么是事務(wù),以及該如何使用


          9a7b9c36720bf02b78acb6c61943c85e.webp

          abstract.png概述

          定義

          MySQL的操作使用相信大家都不陌生,即是通過一條條的SQL語句去完成的。而如果我們將一條或多條對數(shù)據(jù)庫操作的SQL語句視作一個整體來看,即是所謂的Transaction事務(wù)。對于事務(wù)而言,其需要滿足四個特性——ACID

          Note

          • 對于MySQL數(shù)據(jù)庫而言,并不是所有的存儲引擎都支持事務(wù)。具體地,對于InnoDB、NDB存儲引擎而言,其是支持事務(wù)的;但對于MyISAM存儲引擎而言,是不支持事務(wù)的

          ACID

          Atomicity 原子性

          事務(wù)的Atomicity原子性指的是,對于一個事務(wù)而言其是執(zhí)行的最小單位,不可以被分割。具體地,對于一個事務(wù)中的若干條SQL語句而言,要么這些SQL語句全部不執(zhí)行,要么這些SQL語句全部執(zhí)行。而不允許在一個事務(wù)中出現(xiàn)只執(zhí)行一部分SQL語句而另一部分SQL語句未執(zhí)行的情況

          這里我們以A給B的賬戶轉(zhuǎn)賬10元為例進行說明。對于這個轉(zhuǎn)賬操作來說,我們可以大致分為兩個步驟

          1. 將A賬戶余額減去10
          2. 將B賬戶余額增加10

          顯然上述兩個步驟要么全部執(zhí)行了,要么全部不執(zhí)行了。而其它任何的執(zhí)行情況來說,即只執(zhí)行步驟1或只執(zhí)行步驟2,顯然都是錯誤的

          Consistency 一致性

          數(shù)據(jù)庫始終是對真實的現(xiàn)實世界進行描述的。故如果數(shù)據(jù)庫中的數(shù)據(jù)能夠滿足現(xiàn)實世界的約束,即認為是符合Consistency一致性的。這里關(guān)于約束、規(guī)則的定義是主觀的,比如上面轉(zhuǎn)賬的例子中,如果我們可以將 A、B兩人賬戶的總額加在一起是不變 作為約束。還可以根據(jù)實際業(yè)務(wù)需要,比如根據(jù)賬戶類型借記卡還是信用卡,來考慮是否將 賬戶余額不允許為負值 作為約束。事實上對于MySQL而言,其語法也在一定程度上支持約束。比如NOT NULL非空約束

          Isolation 隔離性

          Isolation隔離性指的是多個事務(wù)并發(fā)執(zhí)行時不應(yīng)相互影響。同樣還是以A給B轉(zhuǎn)賬為例。不同的是,這里假設(shè)兩次轉(zhuǎn)賬操作是并發(fā)的。可以看到當兩個轉(zhuǎn)賬事務(wù)按如下方式交錯執(zhí)行時,即會出現(xiàn)一些意外的情況

          d31bc6e3afe173f68900c6617f3bfe5c.webp

          figure 1.png

          A給B轉(zhuǎn)了兩次賬,共計20元。結(jié)果B的賬戶上是多了20元,可是A的賬戶上卻只少了10元。這種局面顯然是不應(yīng)該出現(xiàn)的

          Durability 持久性

          所謂Durability持久性是指當事務(wù)完成后對數(shù)據(jù)的修改應(yīng)該落到磁盤中,即被持久化存儲

          狀態(tài)

          對于事務(wù)一個而言,其通常存在下面的幾種狀態(tài)

          • 活動狀態(tài)

          正在執(zhí)行該事務(wù)中的數(shù)據(jù)庫操作

          • 部分提交狀態(tài)

          該事務(wù)中的數(shù)據(jù)庫操作雖然全部執(zhí)行完了。但此時均只是發(fā)生在內(nèi)存中,還未刷新同步到硬盤

          • 提交狀態(tài)

          處于部分提交狀態(tài)的事務(wù)將數(shù)據(jù)同步刷新到硬盤

          • 失敗狀態(tài)

          對處于活動狀態(tài)、部分提交狀態(tài)的事務(wù)而言,如果發(fā)生意外(數(shù)據(jù)庫出現(xiàn)錯誤、斷電等)或主動停止當前事務(wù),則該事務(wù)處于失敗狀態(tài)

          • 中止狀態(tài)

          根據(jù)事務(wù)的原子性可知,當事務(wù)處于失敗狀態(tài)時需要通過Rollback回滾將數(shù)據(jù)庫數(shù)據(jù)恢復到執(zhí)行事務(wù)之前的狀態(tài)。當Rollback回滾操作完成后,該事務(wù)即為中止狀態(tài)

          上述各狀態(tài)之間的轉(zhuǎn)換關(guān)系,如下圖所示

          9936d7e7da2ee958b7c7d03a5a0a5357.webp

          figure 2.png基本使用

          開啟事務(wù)

          下面語句均可開啟一個事務(wù)。其中對于start transaction語句而言,其后面還可使用修飾符,若同時使用多個修飾符需通過逗號進行分隔。具體地,修飾符有以下幾種:

          • READ ONLY:只讀事務(wù)
          • READ WRITE:讀寫事務(wù)
          • WITH CONSISTENT SNAPSHOT:一致性讀

          如果不使用修飾符則默認為讀寫事務(wù)。值得一提的是,不可同時使用READ ONLY、READ WRITE修飾符

          --?開啟事務(wù)
          begin;
          --?開啟事務(wù)
          start?transaction?[修飾符];

          提交事務(wù)

          通過下面的SQL語句即可提交事務(wù)

          --?提交事務(wù)
          commit

          下圖即為一個事務(wù)操作的基本流程,可以看到該事務(wù)中間只含有一條數(shù)據(jù)庫操作。事實上,在事務(wù)中可以包含若干條數(shù)據(jù)庫操作語句

          bf67aa44680206e7cf9b042c890507f4.webp

          figure 3.png

          中止事務(wù)

          在事務(wù)中,如果發(fā)現(xiàn)某個SQL語句輸入錯誤了。可以通過下面的語句進行回滾來中止事務(wù)

          rollback;

          下圖即為一個事務(wù)中途中止的示例??梢钥吹酵ㄟ^rollback回滾操作,即可將數(shù)據(jù)庫數(shù)據(jù)恢復到該事務(wù)開始之前的狀態(tài)。這里我們演示的是主動中止事務(wù)的情況。事實上,當事務(wù)在執(zhí)行過程中發(fā)生了錯誤而無法繼續(xù)執(zhí)行時,事務(wù)會自動進行回滾

          43acec5af3ca2d84524fcb8ef4d91031.webp

          figure 4.png

          保存點

          在上面的例子中,我們在事務(wù)執(zhí)行時由于手抖了把SQL語句中的 "電氣工程" 寫成 "電器工程",就不得不進行全部回滾。然后又要從頭執(zhí)行事務(wù)中所有數(shù)據(jù)庫操作,此舉顯然很麻煩。為此savepoint保存點應(yīng)運而生,我們可以在事務(wù)執(zhí)行過程中適當建立保存點。這樣后續(xù)如果需要回滾就不必回滾到事務(wù)開啟前最初的狀態(tài),而只需回滾到指定保存點所在的狀態(tài)即可

          保存點相關(guān)的SQL語句如下所示

          --?建立保存點
          savepoint?<保存點名稱>;
          --?回滾到指定保存點,其中savepoint關(guān)鍵字可省略
          rollback?to?[savepoint]?<保存點名稱>;
          --?刪除指定保存點
          release?savepoint?<保存點名稱>;

          下圖即生動形象地反應(yīng)了關(guān)于保存點的使用姿勢

          daa2bfb9d59e72c921209ff0807c0e29.webp

          figure 5.png

          自動提交

          所謂自動提交指的是,如果我們不顯式地通過 start transaction 或 begin 開啟事務(wù)的話,則對于每條SQL語句而言均視為一個事務(wù)進行執(zhí)行。該特性可通過系統(tǒng)變量autocommit進行使能控制,其默認為on。具體可通過下面的SQL語句查看、修改該系統(tǒng)變量

          --?查看系統(tǒng)變量?autocommit
          show?variables?like?'autocommit';
          --?修改系統(tǒng)變量?autocommit
          set?autocommit?=?{on|off};

          如果我們不想使用自動提交功能的話,具體有以下兩種途徑實現(xiàn)

          • 關(guān)閉autocommit自動提交

          將系統(tǒng)變量autocommit修改為off以關(guān)閉自動提交功能。這樣數(shù)據(jù)庫會將多條SQL語句視為在同一個事務(wù)當中,直到我們顯式地使用 commit提交事務(wù) 或 rollback回滾事務(wù)

          • 顯式地通過start transaction 或 begin開啟事務(wù)

          當我們通過顯式地通過start transaction 或 begin開啟事務(wù)時,即使系統(tǒng)變量autocommit為on。自動提交的功能也會暫時被關(guān)閉。直到該事務(wù)被commit提交 或 rollback回滾

          隱式提交

          所謂隱式提交指的是,當我們通過顯式地通過start transaction、begin開啟事務(wù) 或 關(guān)閉了自動提交功能 后,如果遇到特殊類型的語句時既會導致當前事務(wù)被提交,效果等同于commit語句。這里就會常見的導致隱式提交的操作類型介紹下:

          • DDL類型的SQL語句。例如create、alter、drop等語句
          • 使用鎖控制相關(guān)的語句。例如lock tables、unlock tables等語句
          • MySQL復制的語句。例如{start|stop|reset} slave、change master to等語句
          • 使用、修改mysql庫中的表。例如{alter|create|drop|rename} user、grant、set password等語句
          • 當前事務(wù)還未提交或回滾,就又通過start transaction、begin開啟一個新的事務(wù)。則上一個事務(wù)會被提交
          • 加載數(shù)據(jù)的操作。例如批量導入load data語句
          參考文獻
          1. MySQL是怎樣運行的
          瀏覽 69
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  免费看国产黄色 | 国产精品久久久久久久久毛毛 | 日韩av在线小说 日韩av在线直播 | 国产专区123 | 亚洲免费视频播放 |