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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # innodb鎖的模式 ![](https://img.kancloud.cn/2c/df/2cdf7cab6418a8364cebeeef18e10a9a_835x280.png) ## 悲觀鎖(多寫情況) #### 1.是什么? > 每次處理數據時, 都認為別人也會修改, 所以每次處理數據時, 先提前加鎖, 再處理; ## 樂觀鎖(多讀情況) #### &emsp;1.是什么? > 每次處理數據時, 都認為別人不會修改, 所以每次處理數據時, 都不加鎖, 只是在更新數據時, 判斷下別人有沒有在此期間修改過數據; #### &emsp;2.兩種實現方式 #### &emsp;&emsp;2.1 \. 版本號機制 > 一般是在數據表中加上一個數據版本號version字段,表示數據被修改的次數,當數據被修改時,version值會加一。當線程A要更新數據值時,在讀取數據的同時也會讀取version值,在提交更新時,若剛才讀取到的version值為當前數據庫中的version值相等時才更新,否則重試更新操作,直到更新成功。 #### &emsp;&emsp;2.2 \. CAS算法 > 即**compare and swap(比較與交換)**,是一種有名的**無鎖算法**。無鎖編程,即不使用鎖的情況下實現多線程之間的變量同步,也就是在沒有線程被阻塞的情況下實現變量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。 ## 共享鎖(讀鎖 s) > 多個事務對于同一數據可以共享一把鎖,都能訪問到數據,但是只能讀不能修改 > 加鎖:? ?select? \* from tb\_student? where id = 1 **lock? in share mode** 釋放:? commit? /? rollback ## 排他鎖 (寫鎖 x): > 排他鎖就是不能與其他所并存,如一個事務獲取了一個數據行的排他鎖,其他事務就不能再獲取該行的其他鎖,包括共享鎖和排他鎖,但是獲取排他鎖的事務是可以對數據就行讀取和修改。 > InnoDB引擎默認的修改數據語句,update,delete,insert都會自動給涉及到的數據加上排他鎖,select語句默認不會加任何鎖類型 > 加過排他鎖的數據行在其他事務種是不能修改數據的,也不能通過for update和lock in share mode鎖的方式查詢數據,但可以直接通過select ...from...查詢數據,因為普通查詢沒有任何鎖機制 > select? \*? from? tb\_student where id = 1?**?for update** ### 表鎖 > 加表鎖:? ? ? ?lock table \[tableName\] \[read | write\] > 釋放表鎖:? ?unlock table ###意向鎖 表鎖和行鎖存在沖突,比如: 1. transactionA獲取了tableA中某一行的共享鎖,其它事務就不能再修改這行數據了 2. trsactionB如果獲取了tableA的表級排它鎖,就可以對tableA的所有數據修改 這里 transactionB的表鎖和transactionA的行鎖就是沖突的 意向鎖就是為了解決行鎖和表鎖的沖突,意向鎖本身也是表級別的鎖,事務在獲取行鎖前,必須先獲取相應的意向鎖,意向鎖相當于一個標記,用來顯示當前是否有事務鎖住了表中的某一行 事務在獲取表中某一行的 ?共享鎖 前必須先獲取到 意向共享鎖或者更高級別的鎖 事務在獲取表中某一行的 排它鎖 前必須先獲取到 意向排它鎖 #### 意向共享鎖(Is): #### 意向排他鎖 (IX): ![](https://img.kancloud.cn/34/d2/34d23f2b28705b8dce9546081bd584cd_882x556.png) ### 記錄鎖(Record Lock) select \* from \[tb\_name\] where? ?id =? #{id}? for update id列上有唯一索引,并且查詢條件可以唯一確定一條記錄,這時候innodb使用記錄鎖,只會鎖住查出來的這一行記錄 ### 間隙鎖(Gap Lock): > where后面的字段有索引,但不是唯一索引,或者使用了>,? <? 等范圍的查詢條件時,查詢條件范圍內的索引值之間的間隙會被加鎖,結果就是被加鎖的間隙之間不能插入索引值 > 區間是左開右閉的 > 在InnoDB下,間隙鎖的產生需要滿足三個條件: * 隔離級別為RR * 當前讀 * 查詢條件能夠走到索引 ### 鎖(Next-key Lock) 是行鎖與間隙鎖的組合 # 死鎖 ### 什么是死鎖? > 當兩個事務都需要獲得對方持有的排他鎖才能完成事務,這樣就導致了循環鎖等待,也就是常見的死鎖類型 ### 產生的原因? > Mysql行級鎖并不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種,如果一條sql語句操作了主鍵索引,那么Mysql就會鎖定這個主鍵索引,如果sql語句操作的是非主鍵索引,那么Mysql會先鎖定這個非主鍵索引,再去鎖定主鍵索引。 > 在UPDATE 和 DELETE操作時Mysql不僅會鎖定所有WHERE 條件掃描過得索引,還會鎖定相鄰的鍵值。 ### 解決死鎖的方法? > 1、? 數據庫參數 > 2、? 應用中盡量約定程序讀取表的順序一樣 > 3、? 應用中處理一個表時,盡量對處理的順序排序 > 4、? 調整事務隔離級別(避免兩個事務同時操作一行不存在的數據,容易發生死鎖) ### 死鎖的案例 > Test:(ID,STATE,TIME)? 主鍵索引:ID? 非主鍵索引:STATE > 當執行"UPDATE? STATE =1011 WHERE STATE=1000"? 語句的時候會鎖定STATE索引,由于STATE 是非主鍵索引,所以Mysql還會去請求鎖定ID索引 > 當另一個SQL語句與語句1幾乎同時執行時:“UPDATE STATE=1010 WHERE ID=1”? 對于語句2 Mysql會先鎖定ID索引,由于語句2操作了STATE字段,所以Mysql還會請求鎖定STATE索引。這時。彼此鎖定著對方需要的索引,又都在等待對方釋放鎖定。所以出現了"死鎖"的情況。 # MVCC * ## 是什么? > `MVCC (Multiversion Concurrency Control)`?中文全稱叫多版本并發控制,是現代數據庫(包括?`MySQL`、`Oracle`、`PostgreSQL`?等)引擎實現中常用的處理讀寫沖突的手段,目的在于提高數據庫高并發場景下的吞吐性能。 * ## 實現流程? #### &emsp;&emsp;1.update修改的實現流程 > 1. 通過主鍵(或隱藏主鍵 DB_ROW_ID), 對該行加排他鎖 > 2. 將這條記錄, 原封不到的放入`undo log`?中, 記做nudolog1; > 3. 執行修改, 會產生新的 事務, 所以在`undo log`?中產生新的一條記錄,記做undolog2, 相比較undolog1, undolog2中會修改兩個值; > 3.1 修改第一個值: 事務ID(DATA_TRX_ID), 將其改成新的事務ID(例如 原本nudolog1中該值是1 , 那么undolog2中改成2); > 3.2 修改第二個值: 指向回滾段指針(DATA_ROLL_PRE), 將其值指向undolog1; > 如果對該行記錄執行連續的update操作, 則重復上面2,3操作, 然后`undo log`?會形成鏈表, 遍歷這個鏈表可以看到這條記錄的變遷; > 4. 記錄?`redo log`,包括?`undo log`?中的修改 #### &emsp;&emsp;2.delete修改的實現流程 #### &emsp;&emsp;3.insert修改的實現流程 * ## 如何實現一致性讀? > 1.RU隔離級別下 > 直接讀版本的最新記錄就可以 > 2.RC 和 RR隔離級別下 (MVCC運行在這兩個級別下) > 在?`SELECT`?數據時就會用到版本鏈, 但是要讀哪個版本下的記錄就要決定于 , `ReadView`(可讀視圖)了 > 3.S隔離級別下 > 是通過加鎖互斥來訪問數據的, 用不到MVCC * # 相關命令操作
                  <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>

                              哎呀哎呀视频在线观看