日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

数据库各种锁详解

發(fā)布時(shí)間:2023/12/3 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据库各种锁详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 排他鎖
  • 共享鎖
  • 更新鎖
  • 意向鎖
  • 鎖的粒度
  • 數(shù)據(jù)庫自動加鎖
  • 手動加鎖
  • 各種鎖之間的兼容問題

排他鎖

Exclusive Locks,英譯:排他鎖,簡稱 X 鎖,又稱為寫鎖或獨(dú)占鎖。排他鎖分為表級排他鎖和行級排他鎖。

如果事務(wù) T1 對數(shù)據(jù)行對象 A 加上了行級排他鎖,那么事務(wù) T1 可以對數(shù)據(jù)行對象 A 進(jìn)行讀取和更新操作,其他事務(wù)則只能對數(shù)據(jù)行對象 A 進(jìn)行讀取操作,而不能進(jìn)行更新操作,并且其它事務(wù)不能再往數(shù)據(jù)行對象 A 上加任何類型的鎖,直到 T1 釋放了行級排他鎖。

MySQL 的 InnoDB 引擎默認(rèn)的修改數(shù)據(jù)語句 update、delete、insert 都會自動給涉及到的數(shù)據(jù)加上行級排他鎖,而 select 語句默認(rèn)不會加任何鎖,如果查詢的時(shí)候要加行級排他鎖可以使用 select ...for update 語句,加行級共享鎖可以使用 select ... lock in share mode 語句。

所以加過行級排他鎖的數(shù)據(jù)行其他事務(wù)是不能通過 for update 和 lock in share mode 方式查詢數(shù)據(jù),但可以直接通過 select ...from... 查詢數(shù)據(jù),因?yàn)槠胀ú樵儧]有加任何鎖。

事務(wù) T1 如果對某張表加了表級排他鎖,表示事務(wù) T1 可以對該表中的所有記錄進(jìn)行查詢和修改,而其它事務(wù)只能查詢不能修改。并且其它事務(wù)不能再往這張表加任何類型的表級鎖,也不能給表中的數(shù)據(jù)行加任何的行級鎖。

共享鎖

Shared Lock,英譯:共享鎖,簡稱 S 鎖,又稱讀鎖。共享鎖分為表級共享鎖和行級共享鎖。

顧名思義,共享鎖就是多個(gè)事務(wù)對于同一數(shù)據(jù)可以共享一把鎖,都能訪問到數(shù)據(jù),但是只能讀不能修改。即共享鎖不阻塞其他事務(wù)的讀操作,但阻塞寫操作。

當(dāng)事務(wù) T1 為數(shù)據(jù)行對象 A 加上行級共享鎖后,事務(wù) T1 可以對數(shù)據(jù)行對象 A 進(jìn)行讀操作,但不能進(jìn)行寫操作,并且事務(wù) T2 可以再次對數(shù)據(jù)行對象 A 加行級共享鎖,但是不能加行級排他鎖,也不能加表級排他鎖。大家都可以正常地讀取數(shù)據(jù)行對象 A,在數(shù)據(jù)行對象 A 上的所有共享鎖釋放之前,任何事務(wù)不可以對數(shù)據(jù)行對象 A 進(jìn)行寫操作。

數(shù)據(jù)行對象 A 可以共存多個(gè)行級共享鎖,這被稱為行級共享鎖兼容。加了行級共享鎖的數(shù)據(jù)行對象 A 不能再加行級排他鎖,所以行級共享鎖和行級排他鎖是不兼容的。

當(dāng)事務(wù) T1 為某張表添加了表級共享鎖,表示事務(wù) T1 可以查看表中的所有記錄,但是不能修改,而且其它事務(wù)也只能查看數(shù)據(jù)不能修改數(shù)據(jù)。但是其它事務(wù)可以再往這張表添加表級共享鎖和意向共享鎖,其它事務(wù)也可以往這張表中的記錄添加行級共享鎖;但是其它事務(wù)不能再往這張表添加表級的排他鎖,也不能添加意向排他鎖,其它事務(wù)也不能往這張表中的記錄添加行級排他鎖。

更新鎖

Update Lock,英譯:更新鎖,簡稱 U 鎖。更新鎖只有行級的更新鎖。

當(dāng)事務(wù) T1 給數(shù)據(jù)行對象 A 加上更新鎖后,代表數(shù)據(jù)行對象 A 將在稍后被更新。更新鎖允許其他事務(wù)在事務(wù) T1 操作更新之前讀取數(shù)據(jù)行對象 A,但不可以修改。其他事務(wù)修改數(shù)據(jù)行對象 A 之前會先往數(shù)據(jù)行對象 A 加行級排他鎖,但是發(fā)現(xiàn)數(shù)據(jù)行對象 A 已存在 U 鎖,所以加行級排他鎖失敗,只能等待 U 鎖釋放。

更新鎖與行級共享鎖兼容;更新鎖與表級共享鎖不兼容;更新鎖與更新鎖互不兼容;更新鎖與行級排他鎖不兼容,更新鎖與表級排他鎖不兼容。

因此數(shù)據(jù)行對象 A 不可以再添加更新鎖,但是可以添加行級共享鎖,但是添加行級共享鎖的意義不大,因?yàn)槭聞?wù) T1 找到需要更新的數(shù)據(jù)時(shí),更新鎖直接轉(zhuǎn)為行級排他鎖,開始更新數(shù)據(jù),不需要等待其他事務(wù)釋放行級共享鎖,所以在有更新鎖的數(shù)據(jù)資源上加行級共享鎖就毫無意義了。

意向鎖

在數(shù)據(jù)行對象上加 U、X、S 之前都會先為表或者頁加意向鎖。意向鎖是一種表級鎖,表明“某個(gè)事務(wù)對表中的記錄加了某種鎖或準(zhǔn)備加某種鎖。

常用的意向鎖有三種:
1.Intent Share Lock,英譯:意向共享鎖,簡稱 IS 鎖

事務(wù) T1 在給數(shù)據(jù)行對象添加行級 S 鎖前,要先獲得 IS 鎖。如果表被加了 IS 鎖,說明某個(gè)事務(wù)對這個(gè)表中的某些數(shù)據(jù)行加了行級 S 鎖。當(dāng)其它事務(wù)想要在這個(gè)表上加一個(gè)表級排他鎖時(shí),發(fā)現(xiàn)這個(gè)表已經(jīng)加了意向共享鎖,那么就不可以加表級的排他鎖了。

2.Intent Exclusive Lock,英譯:意向排他鎖,簡稱 IX 鎖

事務(wù)在請求行級 X 鎖前,要先獲得 IX 鎖
事務(wù) T1 修改 user 表的數(shù)據(jù)行對象 A,會給數(shù)據(jù)行對象 A 上一把行級的排他鎖,但是在給數(shù)據(jù)行對象 A 上行級排他鎖前會先給 user 表上一把意向排他鎖,這時(shí)事務(wù) T2 要給 user 表上一個(gè)表級的排他鎖就會被阻塞。

3.Share Intent Exclusive Lock,英譯:共享意向排他鎖,簡稱 SIX 鎖

共享意向排他鎖的意思是,某事務(wù)要讀取整個(gè)表,并更新其中的某些數(shù)據(jù)。

我質(zhì)疑存在這種鎖,在網(wǎng)絡(luò)上找不到關(guān)于共享意向排它鎖的任何資料。

鎖的粒度

鎖的粒度指的是鎖生效的范圍,即行鎖、頁鎖、表鎖等。鎖的粒度一般由數(shù)據(jù)庫自主管理,不同的事務(wù)隔離級別,數(shù)據(jù)庫會有不同的加鎖策略(比如加什么類型的鎖,加什么粒度的鎖)。

數(shù)據(jù)庫自動加鎖

其實(shí)鎖在大多數(shù)情況下都是數(shù)據(jù)庫自動加的,數(shù)據(jù)庫會根據(jù)隔離級別的不同,按照策略來加鎖。

比如這么一條語句:

mysql> update student set class = '高二(3)班';

通過性能分析工具 Profiler 跟蹤 sql 發(fā)現(xiàn),數(shù)據(jù)庫系統(tǒng)會逐行先獲取 U 鎖,然后轉(zhuǎn)為 X 鎖,對數(shù)據(jù)行進(jìn)行更新,更新完后并不釋放 X 鎖,接著繼續(xù)獲取下一行的 U 鎖,轉(zhuǎn)為 X 鎖,更新數(shù)據(jù)…,不斷重復(fù)以上流程,直到全部數(shù)據(jù)行更新完成后,再逐行釋放掉所有的 X 鎖。

而如果加上 where 條件,如:

mysql> update student set class = '高二(3)班' where name = 'liudehua';

如果字段 name 沒有索引,則逐行獲取 U 鎖,如果符合條件,轉(zhuǎn)為 X 鎖,執(zhí)行更新,不釋放 X 鎖;如果不符合條件,釋放 U 鎖。

如果有索引的話,則不需要全表掃描逐行處理,而是直接定位到要更新的數(shù)據(jù)行,然后逐行加上 X 鎖,接著執(zhí)行更新,更新后不釋放 X 鎖,直到所有定位到的數(shù)據(jù)行更新完成后,再逐行釋放 X 鎖。

手動加鎖

手動加行級排他鎖,如下所示:

mysql> begin; -- 開始事務(wù) Query OK, 0 rows affected (0.00 sec)mysql> select * from account where id = 5 for update; -- 查詢到的數(shù)據(jù)行全部加上行級的排他鎖 +----+----------+---------+ | id | NAME | balance | +----+----------+---------+ | 5 | zhangsan | 1000.00 | +----+----------+---------+ 1 row in set (0.00 sec)

手動加行級共享鎖,如下所示:

mysql> begin; Query OK, 0 rows affected (0.00 sec)mysql> select * from account where id = 5 lock in share mode; +----+----------+---------+ | id | NAME | balance | +----+----------+---------+ | 5 | zhangsan | 0.00 | +----+----------+---------+ 1 row in set (0.01 sec)

手動給表加表級的排他鎖,如下所示:

mysql> lock tables account write; -- 給表account加排他鎖,即寫鎖 Query OK, 0 rows affected (0.00 sec)

注:
1.會話 S1 對表 account 加上表級排他鎖后,其它會話不能對該表 account 進(jìn)行查詢和修改操作。
2.會話 S1 對表 account 加上任何表級鎖后,該會話不能對其它非鎖表進(jìn)行任何的操作。

手動給表加表級的共享鎖,如下所示:

mysql> lock tables account read; -- 給表account 加共享鎖,即讀鎖 Query OK, 0 rows affected (0.00 sec)

給多個(gè)表加表級鎖,如下所示:

mysql> lock table user write,account write; Query OK, 0 rows affected (0.00 sec)

手動解鎖,如下所示:

mysql> unlock tables;

各種鎖之間的兼容問題

-行級 S行級 U行級 X表級 S表級 XISIX
行級 S兼容加了 S 鎖不能再加 U 鎖,但是先加 U 鎖,可以再加 S 鎖不兼容兼容不兼容兼容兼容
行級 U加了 S 鎖不能再加 U 鎖,但是先加 U 鎖,可以再加 S 鎖不兼容不兼容不兼容不兼容兼容兼容
行級 X不兼容不兼容不兼容不兼容不兼容兼容兼容
表級 S兼容不兼容不兼容兼容不兼容兼容不兼容
表級 X不兼容不兼容不兼容不兼容不兼容不兼容不兼容
IS兼容不兼容不兼容兼容不兼容兼容兼容
IX兼容兼容兼容不兼容不兼容兼容兼容

總結(jié)

以上是生活随笔為你收集整理的数据库各种锁详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。