鍍金池/ 問答/數(shù)據(jù)庫/ 對(duì)mysql共享鎖定義越讀越懵

對(duì)mysql共享鎖定義越讀越懵

共享鎖定義基本如下:
共享鎖(S鎖)又稱為讀鎖,若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上S鎖,則事務(wù)T只能讀A;其他事務(wù)只能再對(duì)A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這就保證了其他事務(wù)可以讀A,但在T釋放A上的S鎖之前不能對(duì)A做任何修改。

對(duì)著這句話,突然有些語句不是太明白:

1.如果事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上共享鎖,在沒有釋放A上的共享鎖之前,其他事物是否可以對(duì)A加共享鎖?也就是說,同一時(shí)刻,對(duì)象A是否可以有很多事物對(duì)他加共享鎖?
2.如果事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上共享鎖,事物T2沒有對(duì)A加共享鎖,那么T2是否能讀取A的數(shù)據(jù)?如果能讀取數(shù)據(jù),那對(duì)他加共享鎖的意義是什么,因?yàn)槲壹硬患佣寄茏x取數(shù)據(jù)?
3.共享鎖的操作一定是在各個(gè)事務(wù)里面嗎?不用事務(wù)就不能操作共享鎖嗎?
4.實(shí)際場(chǎng)景怎么用?

希望各位大神解答下這4個(gè)疑惑,先謝謝了

回答
編輯回答
瞄小懶
1.如果事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上共享鎖,在沒有釋放A上的共享鎖之前,其他事物是否可以對(duì)A加共享鎖?也就是說,同一時(shí)刻,對(duì)象A是否可以有很多事物對(duì)他加共享鎖?

是的。所謂共享鎖,全稱應(yīng)該為共享讀鎖,即多個(gè)事務(wù)可以同時(shí)加共享鎖,讀取同一個(gè)對(duì)象。這也就是『共享』二字的含義。

2.如果事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上共享鎖,事物T2沒有對(duì)A加共享鎖,那么T2是否能讀取A的數(shù)據(jù)?如果能讀取數(shù)據(jù),那對(duì)他加共享鎖的意義是什么,因?yàn)槲壹硬患佣寄茏x取數(shù)據(jù)?

不能。這是MYSQL數(shù)據(jù)庫設(shè)計(jì)共享鎖一部分,事務(wù)T讀取對(duì)象A之前,必須要加共享鎖;如果事務(wù)T2想要讀取對(duì)象A,那它也要加共享鎖;如果事務(wù)T2想要寫對(duì)象A,那么需要加排它鎖,且此時(shí)有共享鎖,T2必須等到,直到施加在A上的共享鎖被T事務(wù)釋放。

3.共享鎖的操作一定是在各個(gè)事務(wù)里面嗎?不用事務(wù)就不能操作共享鎖嗎?

事務(wù)是關(guān)系型數(shù)據(jù)庫必不可少的一個(gè)概念,它是數(shù)據(jù)庫系統(tǒng)執(zhí)行過程中的一個(gè)邏輯單位。

4.實(shí)際場(chǎng)景怎么用?

多個(gè)事務(wù)對(duì)某個(gè)對(duì)象進(jìn)行同時(shí)讀取的操作之前,都會(huì)加共享鎖。
PS:加鎖協(xié)議是數(shù)據(jù)庫并發(fā)控制的一種手段,這種加鎖機(jī)制是有數(shù)據(jù)庫內(nèi)部機(jī)制完成的,對(duì)開發(fā)者用戶透明,不過可以通過調(diào)整數(shù)據(jù)庫隔離級(jí)別來達(dá)到符合自身業(yè)務(wù)的完整性。

2017年7月25日 11:06
編輯回答
黑與白

一、事務(wù)的ACID屬性

隔離性(isolation):

????隔離性等級(jí):

  • 未提交讀(READ UNCOMMITED) 臟讀,兩個(gè)事務(wù)之間互相可見;
  • 已提交讀(READ COMMITED)符合隔離性的基本概念,一個(gè)事務(wù)進(jìn)行時(shí),其它已提交的事物對(duì)于該事務(wù)是可見的,即可以獲取其它事務(wù)提交的數(shù)據(jù)。
  • 可重復(fù)讀(REPEATABLE READ) InnoDB的默認(rèn)隔離等級(jí)。事務(wù)進(jìn)行時(shí),其它所有事務(wù)對(duì)其不可見,即多次執(zhí)行讀,得到的結(jié)果是一樣的!
  • 可串行化(SERIALIZABLE) 在讀取的每一行數(shù)據(jù)上都加鎖,會(huì)造成大量的鎖超時(shí)和鎖征用,嚴(yán)格數(shù)據(jù)一致性且沒有并發(fā)是可使用。

????查看系統(tǒng)的事務(wù)隔離級(jí)別:show variables like '%iso%';
????開啟一個(gè)新事務(wù):begin;
????提交一個(gè)事務(wù):commit;
????修改事物的隔離級(jí)別:set session tx_isolation='read-committed';

????clipboard.png

????實(shí)現(xiàn)事務(wù)的隔離性

二、什么是鎖

2.1 鎖

????clipboard.png

2.2 鎖類型

????clipboard.png

2.3 鎖的粒度

MySQL的事務(wù)支持不是綁定在MySQL服務(wù)器本身,而是與存儲(chǔ)引擎相關(guān)

????clipboard.png

????將table_name加表級(jí)鎖命令:lock table table_name write; 寫鎖會(huì)阻塞其它用戶對(duì)該表的‘讀寫’操作,直到寫鎖被釋放:unlock tables;

  1. 鎖的開銷越大,粒度越小,并發(fā)度越高。
  2. 表級(jí)鎖通常是在服務(wù)器層實(shí)現(xiàn)的。
  3. 行級(jí)鎖是存儲(chǔ)引擎層實(shí)現(xiàn)的。innodb的鎖機(jī)制,服務(wù)器層是不知道的

三、回答

3.1 疑惑1

????clipboard.png

????從上面的表可以看出,讀鎖是可以共享的,相互不會(huì)被阻塞的,即多個(gè)線程可以在同一時(shí)間讀取同一資源,而不相互干擾。
????寫鎖是獨(dú)占的,會(huì)阻塞其他的寫鎖和讀鎖,是排它的,這個(gè)是基于數(shù)據(jù)完整性來考慮的。

3.2 疑惑2

????可以讀??!只是讀取的數(shù)據(jù)根據(jù)你事務(wù)的隔離級(jí)別而不同,可重復(fù)讀(REPEATABLE READ) InnoDB的默認(rèn)隔離等級(jí)。

3.3 疑惑3

????將table_name加表級(jí)鎖命令:lock table_name read
????讀鎖:當(dāng)MySQL的一個(gè)進(jìn)程為某一表開啟讀鎖之后,其他的進(jìn)程包含自身都沒有權(quán)利去修改這表表的內(nèi)容。但是所有的進(jìn)程還是可以讀出表里面的內(nèi)容的。但是不能實(shí)現(xiàn)更新。

3.4 疑惑4

????應(yīng)該在實(shí)際開發(fā)中避免大事務(wù)

運(yùn)行時(shí)間長(zhǎng),操作數(shù)據(jù)比較多的事務(wù);

????風(fēng)險(xiǎn):鎖定數(shù)據(jù)太多,回滾時(shí)間長(zhǎng),執(zhí)行時(shí)間長(zhǎng)。

  1. 鎖定太多數(shù)據(jù),造成大量阻塞和鎖超時(shí);
  2. 回滾時(shí)所需時(shí)間比較長(zhǎng),且數(shù)據(jù)仍然會(huì)處于鎖定;
  3. 如果執(zhí)行時(shí)間長(zhǎng),將造成主從延遲,因?yàn)橹挥挟?dāng)主服務(wù)器全部執(zhí)行完寫入日志時(shí),從服務(wù)器才會(huì)開始進(jìn)行同步,造成延遲。

????解決思路:

  1. 避免一次處理太多數(shù)據(jù),可以分批次處理;
  2. 移出不必要的SELECT操作,保證事務(wù)中只有必要的寫操作。
2018年2月6日 05:44