久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      相關(guān)免費(fèi)學(xué)習(xí)推薦:mysql數(shù)據(jù)庫(kù)(視頻)

      前言

      • MySQL索引底層數(shù)據(jù)結(jié)構(gòu)與算法
      • MySQL性能優(yōu)化原理-前篇
      • MySQL性能優(yōu)化-實(shí)踐篇1
      • MySQL性能優(yōu)化-實(shí)踐篇2

      前面我們講了MySQL數(shù)據(jù)庫(kù)底層的數(shù)據(jù)結(jié)構(gòu)與算法、MySQL性能優(yōu)化篇一些內(nèi)容。我們?cè)賮?lái)聊聊MySQL的鎖與事務(wù)隔離級(jí)別,分上下兩篇,本篇重點(diǎn)講MySQL的行鎖與事務(wù)隔離級(jí)別。

      鎖定義

      鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問(wèn)某一資源的機(jī)制。

      在數(shù)據(jù)庫(kù)中,除了傳統(tǒng)的計(jì)算資源(如CPU、RAM、I/O等)的爭(zhēng)用以外,數(shù)據(jù)也是一種供需要用戶共享的資源。如何保證數(shù)據(jù)并發(fā)訪問(wèn)的一致性、有效性是所有數(shù)據(jù)庫(kù)必須解決的一個(gè)問(wèn)題,鎖沖突也是影響數(shù)據(jù)庫(kù)并發(fā)訪問(wèn)性能的一個(gè)重要因素。

      鎖分類(lèi)

      • 從性能上分為樂(lè)觀鎖(用版本對(duì)比來(lái)實(shí)現(xiàn))和 悲觀鎖
      • 從數(shù)據(jù)庫(kù)操作類(lèi)型分為:讀鎖寫(xiě)鎖 (都屬于悲觀鎖)
        • 讀鎖(共享鎖):針對(duì)同一份數(shù)據(jù),多個(gè)讀操作可以同時(shí)進(jìn)行而不會(huì)互相影響;
        • 寫(xiě)鎖(排它鎖):當(dāng)前寫(xiě)操作沒(méi)有完成之前,它會(huì)阻斷其它寫(xiě)鎖和讀鎖。
      • 從數(shù)據(jù)庫(kù)操作的粒度分為:表鎖行鎖

      對(duì)于鎖深入的理解,可以查看《關(guān)于Java中鎖的理解》。

      MySQL的鎖

      • 行鎖(Record Locks)

      • 間隙鎖(Gap Locks)

      • 臨鍵鎖(Next-key Locks)

      • 共享鎖/排他鎖(Shared and Exclusive Locks)

      • 意向共享鎖/意向排他鎖(Intention Shared and Exclusive Locks)

      • 插入意向鎖(Insert Intention Locks)

      • 自增鎖(Auto-inc Locks)

      • 預(yù)測(cè)鎖,這種鎖主要用于存儲(chǔ)了空間數(shù)據(jù)的空間索引。

      下篇來(lái)分別聊聊,本篇重點(diǎn)是行鎖以及事務(wù)隔離級(jí)別。

      表鎖

      每次操作鎖住整張表。

      • 開(kāi)銷(xiāo)小,加鎖快;
      • 不會(huì)出現(xiàn)死鎖;
      • 鎖粒度大,發(fā)生鎖沖突的概率最高;
      • 并發(fā)度最低。

      基本操作

      示例表,如下:

      # 建表SQLCREATE TABLE mylock (    id INT(11) NOT NULL AUTO_INCREMENT,    NAME VARCHAR(20) DEFAULT NULL,     PRIMARY KEY(id) ) ENGINE = MyISAM DEFAULT CHARSET = utf8;  # 插入數(shù)據(jù)INSERT INTO`test`.`mylock`(`id`,`NAME`) VALUES ('1','a');  INSERT INTO`test`.`mylock`(`id`,`NAME`) VALUES ('2','b');  INSERT INTO`test`.`mylock`(`id`,`NAME`) VALUES ('3','c');  INSERT INTO`test`.`mylock`(`id`,`NAME`) VALUES ('4','d');復(fù)制代碼
      • 手動(dòng)增加表鎖
      lock table 表名稱(chēng) read(write), 表名稱(chēng)2 read(write);復(fù)制代碼
      • 查看表上加過(guò)的鎖
      show open tables;復(fù)制代碼
      • 刪除表鎖
      unlock tables;復(fù)制代碼

      案例分析 — 加讀鎖

      LOCK TABLE mylock read;復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      當(dāng)前 session 和其他 seesion 都可以讀該表;

      當(dāng)前 session 中插入或者更新鎖定表都會(huì)報(bào)錯(cuò),其他 session 插入或者更新則會(huì)等待。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      案例分析 — 加寫(xiě)鎖

      LOCK TABLE mylock WRITE;復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      當(dāng)前 session 對(duì)該表的增刪改查都沒(méi)有問(wèn)題,其他 session 對(duì)該表的所有操作都會(huì)被阻塞 。

      案例結(jié)論

      MyISAM 在執(zhí)行查詢語(yǔ)句(SELECT)前,會(huì)自動(dòng)給涉及的所有表加讀鎖;在執(zhí)行增刪改查操作前,會(huì)自動(dòng)給涉及的表加寫(xiě)鎖。

      • 對(duì) MyISAM 表的讀操作(加讀鎖),不會(huì)阻塞其他進(jìn)程同一表的讀請(qǐng)求,但會(huì)阻塞對(duì)同一表的寫(xiě)請(qǐng)求。只有當(dāng)讀鎖釋放后,才會(huì)執(zhí)行其他進(jìn)程的寫(xiě)操作。
      • 對(duì) MyISAM 表的寫(xiě)操作(加寫(xiě)鎖),會(huì)阻塞其他進(jìn)程對(duì)同一表的讀和寫(xiě)操作,只有當(dāng)寫(xiě)鎖釋放后,才會(huì)執(zhí)行其他進(jìn)程的讀寫(xiě)操作。

      總結(jié):讀鎖會(huì)阻塞寫(xiě),但不會(huì)阻塞讀;而寫(xiě)鎖則會(huì)把讀和寫(xiě)都阻塞。

      行鎖

      每次操作鎖住一行數(shù)據(jù)。

      • 開(kāi)銷(xiāo)大,加鎖慢;
      • 會(huì)出現(xiàn)死鎖;
      • 鎖定粒度最小,發(fā)生鎖沖突的概率最低;
      • 并發(fā)度最高。

      InnoDB 和 MyISAM 的最大不同點(diǎn):

      • 支持事務(wù)(TRANSACTION)
      • 支持行級(jí)鎖

      行鎖支持事務(wù)

      事務(wù)(Transaction)及其 ACID 屬性

      事務(wù)是由一組 SQL 語(yǔ)句組成的邏輯處理單元,事務(wù)具有以下四個(gè)屬性,通常簡(jiǎn)稱(chēng)為事務(wù)的 ACID屬性

      • 原子性(Atomicity):事務(wù)是一個(gè)原子操作單元,其對(duì)數(shù)據(jù)的修改,要么全部執(zhí)行,要么全部不執(zhí)行。
      • 一致性(Consistent):在事務(wù)開(kāi)始和完成時(shí),數(shù)據(jù)都必須保持一致?tīng)顟B(tài)。這意味著所有相關(guān)的數(shù)據(jù)規(guī)則都必須應(yīng)用于事務(wù)的修改,以保持?jǐn)?shù)據(jù)的完整性;事務(wù)結(jié)束時(shí),所有的內(nèi)部數(shù)據(jù)結(jié)構(gòu)(如B+樹(shù)索引或雙向鏈表)也都必須是正確的。
      • 隔離性(Lsolation):數(shù)據(jù)庫(kù)系統(tǒng)提供一定的隔離機(jī)制,保障事務(wù)在不受外部并發(fā)操作影響的“獨(dú)立”環(huán)境執(zhí)行。這意味著事務(wù)處理過(guò)程中的中間狀態(tài)對(duì)外部是不可見(jiàn)的,反之亦然。
      • 持久性(Durable):事務(wù)完成之后,它對(duì)于數(shù)據(jù)的修改是永久性的,即使出現(xiàn)系統(tǒng)故障也能保持。

      并發(fā)事務(wù)處理帶來(lái)的問(wèn)題

      • 更新丟失(Lost Update)

      當(dāng)兩個(gè)或多個(gè)事務(wù)選擇同一行,然后基于最初選定的值更新該行值,由于每個(gè)事務(wù)都不知道其他事務(wù)的存在,就會(huì)發(fā)生丟失更新問(wèn)題,最后的更新覆蓋來(lái)其他事務(wù)所做的更新。

      • 臟讀(Dirty Reads)

      一個(gè)事務(wù)正在對(duì)一條記錄做修改,在這個(gè)事務(wù)完成并提交前,這個(gè)條記錄的數(shù)據(jù)就處于不一致的狀態(tài);這時(shí)另外一個(gè)事務(wù)也來(lái)讀取同一條記錄,如果不加控制,第二個(gè)事務(wù)讀取來(lái)這些“臟”數(shù)據(jù),并據(jù)此做進(jìn)一步的處理,就會(huì)產(chǎn)生未提交的數(shù)據(jù)依賴關(guān)系。這種現(xiàn)象被形象的叫做“臟讀”。

      總結(jié):事務(wù)A讀取到來(lái)事務(wù)B已經(jīng)修改但尚未提交的數(shù)據(jù),還在這個(gè)數(shù)據(jù)基礎(chǔ)上做來(lái)操作。此時(shí),如果事務(wù)B回滾,事務(wù)A讀取的數(shù)據(jù)無(wú)效,不符合一致性要求。

      • 不可重復(fù)讀(Non-Repeatable Reads)

      一個(gè)事務(wù)在讀取某些數(shù)據(jù)后的某個(gè)時(shí)間,再次讀取以前讀過(guò)的數(shù)據(jù),卻發(fā)現(xiàn)其讀出的數(shù)據(jù)已經(jīng)發(fā)生來(lái)改變、或某些記錄已經(jīng)被刪除了,這種現(xiàn)象就叫做“不可重復(fù)讀”。

      總結(jié):事務(wù)A讀取到了事務(wù)B已經(jīng)提交的修改數(shù)據(jù),不符合隔離性。

      • 幻讀(Phantom Reads)

      一個(gè)事務(wù)按相同的查詢條件重新讀取以前檢索過(guò)的數(shù)據(jù),卻發(fā)現(xiàn)其他事務(wù)插入了滿足其查詢條件的新數(shù)據(jù),這種現(xiàn)象就稱(chēng)為“幻讀”。

      總結(jié):事務(wù)A讀取到了事務(wù)B提交的新增數(shù)據(jù),不符合隔離性。

      事務(wù)隔離級(jí)別

      “臟讀”、“不可重復(fù)讀”、“幻讀”,其實(shí)都是數(shù)據(jù)庫(kù)讀一致性問(wèn)題,必須由數(shù)據(jù)庫(kù)提供一定的事務(wù)隔離機(jī)制來(lái)解決。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      數(shù)據(jù)庫(kù)的事務(wù)隔離越嚴(yán)格,并發(fā)副作用越小,但付出的代價(jià)也就越大,因?yàn)槭聞?wù)隔離實(shí)質(zhì)上就是使事務(wù)在一定程度上“串行化”進(jìn)行,這顯然與“并發(fā)”是矛盾的。

      同時(shí),不同應(yīng)用對(duì)讀一致性和事務(wù)隔離程度的要求也是不同的,比如許多應(yīng)用對(duì)“不可重復(fù)讀”和“幻讀” 并不敏感,可能更關(guān)系數(shù)據(jù)并發(fā)訪問(wèn)的能力。

      查看當(dāng)前數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別

      show variables like 'tx_isolation';復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      設(shè)置事務(wù)隔離級(jí)別

      set tx_isolation='REPEATABLE-READ';復(fù)制代碼

      數(shù)據(jù)庫(kù)版本是5.7,隔離級(jí)別是Repeatable-Read(可重復(fù)讀),不同的數(shù)據(jù)庫(kù)版本和隔離級(jí)別對(duì)語(yǔ)句的執(zhí)行結(jié)果影響很大。所以需要說(shuō)明版本和隔離級(jí)別

      行鎖與隔離級(jí)別案例分析

      事務(wù)控制語(yǔ)句

      • BEGINSTART TRANSACTION;顯式地開(kāi)啟一個(gè)事務(wù);
      • COMMIT;也可以使用 COMMIT WORK,不過(guò)二者是等價(jià)的。COMMIT會(huì)提交事務(wù),并使已對(duì)數(shù)據(jù)庫(kù)進(jìn)行的所有修改稱(chēng)為永久性的;
      • ROLLBACK;有可以使用 ROLLBACK WORK,不過(guò)二者是等價(jià)的?;貪L會(huì)結(jié)束用戶的事務(wù),并撤銷(xiāo)正在進(jìn)行的所有未提交的修改;
      • SAVEPOINT identifier;SAVEPOINT允許在事務(wù)中創(chuàng)建一個(gè)保存點(diǎn),一個(gè)事務(wù)中可以有多個(gè)SAVEPOINT;
      • RELEASE SAVEPOINT identifier;刪除一個(gè)事務(wù)的保存點(diǎn),當(dāng)沒(méi)有指定的保存點(diǎn)時(shí),執(zhí)行該語(yǔ)句會(huì)拋出一個(gè)異常;
      • ROLLBACK TO identifier;把事務(wù)回滾到標(biāo)記點(diǎn);
      • SET TRANSACTION;用來(lái)設(shè)置事務(wù)的隔離級(jí)別。InnoDB存儲(chǔ)引擎提供事務(wù)的隔離級(jí)別有READ UNCOMMITTEDREAD COMMITTED、REPEATABLE READSERIALIZABLE。

      事務(wù)處理方法

      MYSQL 事務(wù)處理主要有兩種方法:

      1. BEGIN, ROLLBACK, COMMIT來(lái)實(shí)現(xiàn)
        • BEGIN 開(kāi)始一個(gè)事務(wù)
        • ROLLBACK 事務(wù)回滾
        • COMMIT 事務(wù)確認(rèn)
      1. 直接用 SET 來(lái)改變 MySQL 的自動(dòng)提交模式:
        • SET AUTOCOMMIT=0 禁止自動(dòng)提交
        • SET AUTOCOMMIT=1`` 開(kāi)啟自動(dòng)提交

      示例表,如下:

      CREATE TABLE `user` (    `id` INT (11) NOT NULL AUTO_INCREMENT,    `name` VARCHAR (255) DEFAULT NULL,    `balance` INT (11) DEFAULT NULL,     PRIMARY KEY (`id`) ) ENGINE = INNODB DEFAULT CHARSET = utf8;INSERT INTO `test`.`user` (`name`,`balance`) VALUES ('zhangsan','450');INSERT INTO `test`.`user` (`name`,`balance`) VALUES ('lisi', '16000');INSERT INTO `test`.`user` (`name`,`balance`) VALUES ('wangwu','2400');復(fù)制代碼

      行鎖演示

      一個(gè) session 開(kāi)啟事務(wù)更新不提交,另一個(gè) seesion 更新同一條記錄會(huì)阻塞,更新不同記錄u會(huì)阻塞。

      你知道MySQL鎖與事物隔離級(jí)別嗎?
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      讀未提交

      (1)打開(kāi)一個(gè)客戶端A,并設(shè)置當(dāng)前事務(wù)模式為 read uncommitted (讀未提交),查詢表 user 的初始化值

      set tx_isolation='read-uncommitted';復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (2)在客戶端A的事務(wù)提交之前,打開(kāi)另一個(gè)客戶端B,更新表 user

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (3)這時(shí),雖然客戶端B的事務(wù)還沒(méi)提交,但是在客戶端A就可以查詢到B已經(jīng)更新的數(shù)據(jù)

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (4)一旦客戶端B的事務(wù)因?yàn)槟撤N原因回滾,所有的操作都將會(huì)被撤銷(xiāo),那么客戶端A查詢到的數(shù)據(jù)其實(shí)就是臟數(shù)據(jù)。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (5)在客戶端A執(zhí)行更新語(yǔ)句 update user set balance = balance - 50 where id = 1; zhangsan 的 balance沒(méi)有變成350,居然是400,是不是很奇怪,數(shù)據(jù)不一致啊。如果你這么想就太天真了,在應(yīng)用程序中,我們會(huì)用400-50=350,并不知道其他會(huì)話回滾了,要想解決這個(gè)問(wèn)題可以采用讀已提交的隔離級(jí)別。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      讀已提交

      (1)打開(kāi)一個(gè)客戶端A,并設(shè)置當(dāng)前事務(wù)模式為 read committed (讀已提交),查詢表 user 的所有記錄

      set tx_isolation='read-committed';復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (2)在客戶端A的事務(wù)提交之前,打開(kāi)另一個(gè)客戶端B,更新表 user

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (3)這時(shí),客戶端B的事務(wù)還沒(méi)提交,客戶端A不能查詢到B已經(jīng)更新的數(shù)據(jù),解決了臟讀問(wèn)題。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (4)客戶端B的事務(wù)提交

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (5)客戶端A執(zhí)行與上一步相同的查詢,結(jié)果與上一步不一致,即產(chǎn)生了不可重復(fù)讀的問(wèn)題。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      可重復(fù)讀

      (1)打開(kāi)一個(gè)客戶端A,并設(shè)置當(dāng)前的事務(wù)模式為 repeatable read ,查詢表 user 的所有記錄。

      set tx_isolation='repeatable-read';復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (2)在客戶端A的事務(wù)提交之前,打開(kāi)另一個(gè)客戶端B,更新表 user 并提交。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (3)在客戶端A查詢表 user 的所有記錄,與步驟(1)查詢結(jié)果一直,沒(méi)有出現(xiàn)不可重復(fù)讀的問(wèn)題。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (4)在客戶端A,接著執(zhí)行 update user set balance = balance - 50 where id = 1 , balance 沒(méi)有變成 400 – 50 = 350, zhangsan 的 balance 的值用的是步驟(2) 中的 350 來(lái)計(jì)算的,所以是300,數(shù)據(jù)的一致性倒是沒(méi)有被破壞??芍貜?fù)讀的隔離級(jí)別下使用了 MVCC(multi-version concurrency control)機(jī)制,select 操作不會(huì)更新版本號(hào),是快照讀(歷史版本);insert、update、delete 會(huì)更新版本號(hào),是當(dāng)前讀(當(dāng)前版本)。

      我們下篇來(lái)講 MVCC。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (5)重新打開(kāi)客戶端B,插入一條新數(shù)據(jù)后提交。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (6)在客戶端A查詢表user 的所有記錄,沒(méi)有查出新增數(shù)據(jù),所以沒(méi)有出現(xiàn)幻讀。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (7)驗(yàn)證幻讀 在客戶端A執(zhí)行 update user set balance = 8888 where id = 4; ,能更新成功,再次查詢到客戶端B新增的數(shù)據(jù)。

      串行化

      (1)打開(kāi)一個(gè)客戶端A,并設(shè)置當(dāng)前事務(wù)模式為 serializable ,查詢表 user 的初始值

      set tx_isolation='serializable';復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      (2)打開(kāi)一個(gè)客戶端B,并設(shè)置當(dāng)前事務(wù)模式為 serializable ,插入一條記錄報(bào)錯(cuò),表被鎖了插入失敗,MySQL 中事務(wù)隔離級(jí)別為 serializable 時(shí)會(huì)鎖表,因此不會(huì)出現(xiàn)幻讀的情況,這種隔離級(jí)別并發(fā)性極低,開(kāi)發(fā)中很少會(huì)用到。

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      案例結(jié)論

      InnoDB 存儲(chǔ)引擎由于實(shí)現(xiàn)了行級(jí)鎖定,雖然在鎖定機(jī)制的實(shí)現(xiàn)方面所帶來(lái)的性能損耗可能比表級(jí)鎖定會(huì)更高一下,但是在整體并發(fā)處理能力方面要遠(yuǎn)遠(yuǎn)優(yōu)于 MyISAM 的表級(jí)鎖定的。當(dāng)系統(tǒng)并發(fā)量最高的時(shí)候,InnoDB 的整體性能和 MyISAM 相比就會(huì)有比較明顯的優(yōu)勢(shì)。

      但是,InnoDB 的行級(jí)鎖定同樣也有其脆弱的一面,當(dāng)我們使用不當(dāng)?shù)臅r(shí)候,可能會(huì)讓 InnoDB 的整體性能表現(xiàn)不僅不能比 MyISAM 高,甚至可能會(huì)更差。

      行鎖分析

      通過(guò)檢查 innodb_row_lock 狀態(tài)變量來(lái)分析系統(tǒng)上的行鎖的競(jìng)爭(zhēng)情況:

      show status like 'innodb_row_lock%';復(fù)制代碼
      你知道MySQL鎖與事物隔離級(jí)別嗎?

      對(duì)各個(gè)狀態(tài)量的說(shuō)明如下:

      • Innodb_row_lock_current_waits :當(dāng)前正在等待鎖定的數(shù)量
      • Innodb_row_lock_time :從系統(tǒng)啟動(dòng)到現(xiàn)在鎖定總時(shí)間長(zhǎng)度
      • Innodb_row_lock_time_avg :每次等待所花平均時(shí)間
      • Innodb_row_lock_time_max :從系統(tǒng)啟動(dòng)到現(xiàn)在等待最長(zhǎng)的一次所花時(shí)間
      • Innodb_row_lock_waits :系統(tǒng)啟動(dòng)后到現(xiàn)在總共等待的次數(shù)

      對(duì)于這5個(gè)狀態(tài)變量,比較重要的主要是:

      • Innodb_row_lock_time_avg (等待平均時(shí)長(zhǎng))
      • Innodb_row_lock_waits (等待總次數(shù))
      • Innodb_row_lock_time(等待總時(shí)長(zhǎng))

      尤其是當(dāng)?shù)却螖?shù)很高,而且每次等待時(shí)長(zhǎng)也不小的時(shí)候,我們就需要分析系統(tǒng) 中為什么會(huì)有如此多的等待,然后根據(jù)分析結(jié)果著手制定優(yōu)化計(jì)劃。

      死鎖

      set tx_isolation='repeatable-read';復(fù)制代碼
      Session_1執(zhí)行:select * from user where id=1 for update; Session_2執(zhí)行:select * from user where id=2 for update; Session_1執(zhí)行:select * from user where id=2 for update; Session_2執(zhí)行:select * from user where id=1 for update;復(fù)制代碼

      查看近期死鎖日志信息:

      show engine innodb statusG;復(fù)制代碼

      大多數(shù)情況mysql可以自動(dòng)檢測(cè)死鎖并回滾產(chǎn)生死鎖的那個(gè)事務(wù),但是有些情況 mysql沒(méi)法自動(dòng)檢測(cè)死鎖

      優(yōu)化建議

      1. 盡可能讓所有數(shù)據(jù)檢索都通過(guò)索引來(lái)完成,避免無(wú)索引行鎖升級(jí)為表鎖;
      2. 合理設(shè)計(jì)索引,盡量縮小鎖的范圍;
      3. 盡可能減少檢索條件范圍,避免間隙鎖;
      4. 盡量控制事務(wù)大小,減少鎖定資源量和時(shí)間長(zhǎng)度,涉及事務(wù)加鎖的sql盡量放在事務(wù)最后執(zhí)行;
      5. 盡可能低級(jí)別事務(wù)隔離。

      問(wèn)答

      1. MySQL 默認(rèn)級(jí)別是 repeatable-read,有什么辦法可以解決幻讀媽?zhuān)?/li>

      間隙鎖(Gap Lock)在某些情況下可以解決幻讀問(wèn)題,它是 Innodb 在 可重復(fù)讀 提交下為解決幻讀問(wèn)題時(shí)引入的鎖機(jī)制。要避免幻讀可以用間隙鎖在Session_1 下面執(zhí)行 update user set name = 'hjh' where id > 10 and id <= 20; ,則其他 Session 沒(méi)法在這個(gè)范圍鎖包含的間隙里插入或修改任何數(shù)據(jù)。

      如:user 表有3條數(shù)據(jù), id > 2 and id <=3 會(huì)把第三條記錄鎖住,其他會(huì)話對(duì)則無(wú)法對(duì)第三條記錄做操作。

      你知道MySQL鎖與事物隔離級(jí)別嗎?
      你知道MySQL鎖與事物隔離級(jí)別嗎?
      1. 無(wú)索引鎖會(huì)升級(jí)為表鎖,鎖主要是加在索引上,如果對(duì)非索引字段更新,行鎖可能會(huì)變變鎖。

      客戶端A執(zhí)行: update user set balance = 800 where name = 'zhangsan';

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      客戶端B對(duì)該表任一行執(zhí)行修改、刪除操作都會(huì)阻塞

      你知道MySQL鎖與事物隔離級(jí)別嗎?

      InnoDB 的行鎖是針對(duì)索引加的鎖,不是針對(duì)記錄加的鎖。并且該索引不能失效,否則都會(huì)從行鎖升級(jí)為表鎖。

      1. 鎖定某一行還可以用 local in share mode(共享鎖)for update(排它鎖) ,例如: select * from test_innodb_lock where a = 2 for update; 這樣其他 session 只能讀這行數(shù)據(jù),修改則會(huì)被阻塞,直到鎖定行的 session 提交。

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)