<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 一、事務的基本要素(ACID) **1、原子性(Atomicity):** 事務開始后所有操作,要么全部做完,要么全部不做,不可能停滯在中間環節。事務執行過程中出錯,會回滾到事務開始前的狀態,所有的操作就像沒有發生一樣。也就是說事務是一個不可分割的整體,就像化學中學過的原子,是物質構成的基本單位。 **2、一致性(Consistency):** 事務開始前和結束后,數據庫的完整性約束沒有被破壞 。比如A向B轉賬,不可能A扣了錢,B卻沒收到。 **3、隔離性(Isolation):** 同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾。比如A正在從一張銀行卡中取錢,在A取錢的過程結束前,B不能向這張卡轉賬。 **4、持久性(Durability):** 事務完成后,事務對數據庫的所有更新將被保存到數據庫,不能回滾。 # 二、事務的并發問題 **1、臟讀:** 事務A讀取了事務B更新的數據,然后B回滾操作,那么A讀取到的數據是臟數據 **2、不可重復讀:** 事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新并提交,導致事務A多次讀取同一數據時,結果不一致。 **3、幻讀:** 系統管理員A將數據庫中所有學生的成績從具體分數改為ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。 **小結** 不可重復讀的和幻讀很容易混淆,不可重復讀側重于修改,幻讀側重于新增或刪除。 解決不可重復讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表 # 三、MySQL事務隔離級別 | 事務隔離級別 | 臟讀 | 不可重復讀| 幻讀 | | --- | --- | --- | --- | | 讀未提交(read-uncommitted) | 是 | 是 | 是 | | 讀已提交(read-committed) | 否 | 是 | 是 | | 可重復讀(repeatable-read) | 否 | 否 | 是 | | 串行化(serializable) | 否 | 否 | 否 | # 四、用例子說明各個隔離級別的情況 **1、讀未提交:** (1)打開一個客戶端A,并設置當前事務模式為read uncommitted(未提交讀),查詢表account的初始值: ![](https://img.kancloud.cn/4e/3c/4e3c20c6819f49055e7b9a3080b6a3bd_811x358.png) (2)在客戶端A的事務提交之前,打開另一個客戶端B,更新表account: ![](https://img.kancloud.cn/5b/cc/5bcc1e0876edff3b43ed8b9c6b7b64da_843x447.png) (3)這時,雖然客戶端B的事務還沒提交,但是客戶端A就可以查詢到B已經更新的數據: ![](https://img.kancloud.cn/e4/27/e427dc3ffc63cb47899b080ebf1f6747_703x592.png) (4)一旦客戶端B的事務因為某種原因回滾,所有的操作都將會被撤銷,那客戶端A查詢到的數據其實就是臟數據: ![](https://img.kancloud.cn/39/c7/39c7d552af3eb62fe793580a9d9fee97_859x523.png) **2、讀已提交:** (1)打開一個客戶端A,并設置當前事務模式為read committed(讀已提交),查詢表account的所有記錄: ![](https://img.kancloud.cn/79/b3/79b343919ef5bfeef232afeefd7bff18_840x354.png) (2)在客戶端A的事務提交之前,打開另一個客戶端B,更新表account: ![](https://img.kancloud.cn/7f/e5/7fe5c8f8688f995641ec9bde6c4445b6_836x454.png) (3)這時,客戶端B的事務還沒提交,客戶端A不能查詢到B已經更新的數據,解決了臟讀問題: ![](https://img.kancloud.cn/c0/c3/c0c31fb15174688a8c324669ec11a73d_744x457.png) (4)客戶端B的事務提交 ![](https://img.kancloud.cn/30/4f/304f77bd3ea8cbcc113fd12e80a51684_759x387.png) (5)客戶端A執行與上一步相同的查詢,結果 與上一步不一致,即產生了不可重復讀的問題 ![](https://img.kancloud.cn/9a/d8/9ad8aedff899dc7c46bd8bb2740ad3bc_792x459.png) **3、可重復讀:** (1)打開一個客戶端A,并設置當前事務模式為repeatable read,查詢表account的所有記錄 ![](https://img.kancloud.cn/c8/6b/c86beecd429582b0d7696a8ed5822d55_836x365.png) (2)在客戶端A的事務提交之前,打開另一個客戶端B,更新表account并提交 ![](https://img.kancloud.cn/ee/f9/eef9ff67396d722ddae8806fac8923d8_844x517.png) (3)在客戶端A查詢表account的所有記錄,與步驟(1)查詢結果一致,沒有出現不可重復讀的問題 ![](https://img.kancloud.cn/85/20/8520a09f6710d95cb613d9703134898b_845x452.png) **4、串行化:** (1)打開一個客戶端A,并設置當前事務模式為serializable,查詢表account的初始值: ![](https://img.kancloud.cn/2c/cf/2ccf2d8df630e4293648722de3afd1c9_1462x367.png) (2)打開一個客戶端B,并設置當前事務模式為serializable,插入一條記錄報錯,表被鎖了插入失敗,mysql中事務隔離級別為serializable時會鎖表,因此不會出現幻讀的情況,這種隔離級別并發性極低,開發中很少會用到。 ![](https://img.kancloud.cn/87/37/87377a688a811c097a53413f0ca9af97_1047x212.png) (4)在客戶端A,可重復讀的隔離級別下使用了MVCC機制,select操作不會更新版本號,是快照讀(歷史版本);insert、update和delete會更新版本號,是當前讀(當前版本)。 ![](https://img.kancloud.cn/28/38/2838fc1bf163a6b7521a3b516b0f9e4d_988x513.png) (5)重新打開客戶端B,插入一條新數據后提交 ![](https://img.kancloud.cn/f7/2f/f72f5216423ab1ac89c63e50baef8467_865x189.png) 6)在客戶端A查詢表account的所有記錄,沒有 查出 新增數據,所以沒有出現幻讀 ![](https://img.kancloud.cn/31/1f/311f50668d0d7c26b8fd88645d75312c_963x386.png) # 五、快照(一致性視圖): 可重復讀是在事務開始的時候生成一個當前事務全局性的快照。 而讀提交則是每次執行語句的時候都重新生成一次快照。 **快照要遵循以下規則:** 1. 當前事務內的更新,可以讀到; 2. 版本未提交,不能讀到; 3. 版本已提交,但是卻在快照創建后提交的,不能讀到; 4. 版本已提交,且是在快照創建前提交的,可以讀到; **主要區別:** 可重復讀僅在事務開始是創建一次,而讀提交每次執行語句的時候都要重新創建一次。 # 六、補充: 1、事務隔離級別為讀已提交時,寫數據只會鎖住相應的行 2、事務隔離級別為可重復讀時,如果檢索條件有索引(包括主鍵索引)的時候,默認加鎖方式是next-key 鎖; 如果檢索條件沒有索引,更新數據時會鎖住整張表。一個間隙被事務加了鎖,其他事務是不能在這個間隙插入記錄的,這樣可以防止幻讀。 3、事務隔離級別為串行化時,讀寫數據都會鎖住整張表 4、隔離級別越高,越能保證數據的完整性和一致性,但是對并發性能的影響也越大。 # 七、總結: 1、讀未提交和串行化基本上是不需要考慮的隔離級別,前者不加鎖限制,后者相當于單線程執行,效率太差。 2、讀已提交解決了臟讀問題,行鎖解決了并發更新的問題。并且 MySQL 在可重復讀級別解決了幻讀問題,是通過行鎖和間隙鎖的組合 Next-Key 鎖實現的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看