當(dāng)有多個(gè)查詢?cè)谕粫r(shí)刻修改同一數(shù)據(jù)時(shí)胁勺,便會(huì)產(chǎn)生并發(fā)問(wèn)題檐晕。MySQL通過(guò)鎖來(lái)進(jìn)行并發(fā)控制仇箱。
讀寫鎖
讀鎖又稱共享鎖(S鎖),讀鎖互不干擾惨缆,多個(gè)客戶在同一時(shí)刻可以同時(shí)讀取同一個(gè)資源糜值。
寫鎖又稱排他鎖(X鎖),寫鎖則是排他的坯墨,寫鎖會(huì)阻塞其他寫鎖和讀鎖寂汇,以確保在給定時(shí)間里,只有一個(gè)用戶執(zhí)行寫入捣染,并防止其他用戶讀取正在寫入的同一資源骄瓣。
鎖粒度
鎖粒度指的是鎖定的數(shù)據(jù)量的多少。在給定的資源中液斜,鎖定的數(shù)據(jù)量越少累贤,系統(tǒng)的并發(fā)程度越高叠穆,只要互相不發(fā)生沖突即可少漆。
但是鎖的操作也是需要消耗資源的,所謂的錯(cuò)策略硼被,就是在鎖的開銷和數(shù)據(jù)的安全性之間尋求平衡示损,這種平衡也會(huì)影響性能。
MySQL比較重要的鎖策略有表鎖跟行鎖嚷硫。
表鎖
表鎖是MySQL中最基本的所策略检访,并且是開銷最小的策略。它會(huì)鎖住整張表仔掸。
可以用以下語(yǔ)句獲取表鎖:
LOCK TABLES
tbl_name [[AS] alias] lock_type
[, tbl_name [[AS] alias] lock_type] ...
lock_type: {
READ [LOCAL]
| [LOW_PRIORITY] WRITE
}
UNLOCK TABLES
當(dāng)一個(gè)用戶對(duì)表進(jìn)行寫操作(插入脆贵、刪除、更新等)前起暮,先獲取該表的寫鎖卖氨,這會(huì)阻塞其他用戶對(duì)該表的所有讀寫操作。只有沒有寫鎖時(shí)负懦,其他用戶才能獲取讀鎖筒捺,讀鎖之間不相互阻塞。寫鎖比讀鎖擁有更高的優(yōu)先級(jí)纸厉,因此一個(gè)寫請(qǐng)求可能會(huì)被插入到讀鎖的前面(寫鎖可以插入到鎖隊(duì)列中讀鎖的前面系吭,讀鎖則不能插入到寫鎖的前面)。
READ [LOCAL] 鎖:
- 持有鎖的session可以讀取表颗品,但是不能寫入肯尺。
- 多個(gè)session可以同時(shí)獲取同一個(gè)表的讀鎖沃缘。
- 其他session可以在不顯式獲取讀鎖的情況下讀表。
- 使用LOCAL可以支持某些類型的并發(fā)寫操作蟆盹。在session持有讀鎖的情況下孩灯,允許其他session執(zhí)行不沖突的insert語(yǔ)句(并發(fā)插入),但是逾滥,READ LOCAL如果要在持有鎖的同時(shí)使用服務(wù)器外部的進(jìn)程來(lái)操作數(shù)據(jù)庫(kù)峰档, 則不能使用它。對(duì)于InnoDB 表寨昙,READ LOCAL跟READ一樣讥巡。
[LOW_PRIORITY] WRITE 鎖:
- 持有鎖的session可以讀寫表。
- 只有持有鎖的會(huì)話才能訪問(wèn)該表舔哪。在釋放鎖之前欢顷,沒有其他會(huì)話可以訪問(wèn)它。
- 只有一個(gè)session可以獲得表的寫鎖捉蚤,其他session的寫鎖請(qǐng)求會(huì)被阻塞抬驴。
- 該LOW_PRIORITY修飾符無(wú)效。
具體請(qǐng)看:https://dev.mysql.com/doc/refman/5.7/en/lock-tables.html