六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

數據庫高并發請求,怎么保證數據完整性?詳細說明MySQL/InnoDB的加鎖

[摘要]本文是對MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解,這些在面試中也經常遇到,如數據庫高并發請求,如何保證數據完整性?今天我查閱資料進行了MySQL/Inn...
本文是對MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解,這些在面試中也經常遇到,如數據庫高并發請求,如何保證數據完整性?今天我查閱資料進行了MySQL/InnoDB中加鎖知識點的匯總,這樣也會大家就不會感覺很繁瑣和雜亂了,覺得有用的話就繼續分享吧。apache php mysql

注:MySQL是一個支持插件式存儲引擎的數據庫系統。本文下面的所有介紹,都是基于InnoDB存儲引擎,其他引擎的表現,會有較大的區別。

存儲引擎查看

MySQL給開發者提供了查詢存儲引擎的功能,我這里使用的是MySQL5.6.4,可以使用:

SHOW ENGINES

begin!

樂觀鎖

用數據版本(Version)記錄機制實現,這是樂觀鎖最常用的一種實現方式。何謂數據版本?即為數據增加一個版本標識,一般是通過為數據庫表增加一個數字類型的 “version” 字段來實現。當讀取數據時,將version字段的值一同讀出,數據每更新一次,對此version值加1。當我們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的version值進行比對,如果數據庫表當前版本號與第一次取出來的version值相等,則予以更新,否則認為是過期數據。

舉例

1、數據庫表設計

三個字段,分別是id,value、version

select id,value,version from TABLE where id=#{id}

2、每次更新表中的value字段時,為了防止發生沖突,需要這樣操作

update TABLE
set value=2,version=version+1
where id=#{id} and version=#{version};

悲觀鎖

與樂觀鎖相對應的就是悲觀鎖了。悲觀鎖就是在操作數據時,認為此操作會出現數據沖突,所以在進行每次操作時都要通過獲取鎖才能進行對相同數據的操作,這點跟java中的synchronized很相似,所以悲觀鎖需要耗費較多的時間。另外與樂觀鎖相對應的,悲觀鎖是由數據庫自己實現了的,要用的時候,我們直接調用數據庫的相關語句就可以了。

說到這里,由悲觀鎖涉及到的另外兩個鎖概念就出來了,它們就是共享鎖與排它鎖。共享鎖和排它鎖是悲觀鎖的不同的實現,它倆都屬于悲觀鎖的范疇。

使用,排它鎖 舉例

要使用悲觀鎖,我們必須關閉mysql數據庫的自動提交屬性,因為MySQL默認使用autocommit模式,也就是說,當你執行一個更新操作后,MySQL會立刻將結果進行提交。

我們可以使用命令設置MySQL為非autocommit模式:

set autocommit=0;

# 設置完autocommit后,我們就可以執行我們的正常業務了。具體如下:

# 1. 開始事務

begin;/begin work;/start transaction; (三者選一就可以)

# 2. 查詢表信息

select status from TABLE where id=1 for update;

# 3. 插入一條數據

insert into TABLE (id,value) values (2,2);

# 4. 修改數據為

update TABLE set value=2 where id=1;

# 5. 提交事務

commit;/commit work;

共享鎖

共享鎖又稱讀鎖 read lock,是讀取操作創建的鎖。其他用戶可以并發讀取數據,但任何事務都不能對數據進行修改(獲取數據上的排他鎖),直到已釋放所有共享鎖。

如果事務T對數據A加上共享鎖后,則其他事務只能對A再加共享鎖,不能加排他鎖。獲得共享鎖的事務只能讀數據,不能修改數據

打開第一個查詢窗口

begin;/begin work;/start transaction;  (三者選一就可以)

SELECT * from TABLE where id = 1  lock in share mode;

然后在另一個查詢窗口中,對id為1的數據進行更新

update  TABLE set name="www.souyunku.com" where id =1;

此時,操作界面進入了卡頓狀態,過了超時間,提示錯誤信息

如果在超時前,執行 commit,此更新語句就會成功。

[SQL]update  test_one set name="www.souyunku.com" where id =1;
[Err] 1205 - Lock wait timeout exceeded; try restarting transaction

加上共享鎖后,也提示錯誤信息

update  test_one set name="www.souyunku.com" where id =1 lock in share mode;
[SQL]update  test_one set name="www.souyunku.com" where id =1 lock in share mode;
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'lock in share mode' at line 1

在查詢語句后面增加 LOCK IN SHARE MODE,Mysql會對查詢結果中的每行都加共享鎖,當沒有其他線程對查詢結果集中的任何一行使用排他鎖時,可以成功申請共享鎖,否則會被阻塞。其他線程也可以讀取使用了共享鎖的表,而且這些線程讀取的是同一個版本的數據。

加上共享鎖后,對于update,insert,delete語句會自動加排它鎖。

排它鎖

排他鎖 exclusive lock(也叫writer lock)又稱寫鎖

排它鎖是悲觀鎖的一種實現,在上面悲觀鎖也介紹過

若事務 1 對數據對象A加上X鎖,事務 1 可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到事物 1 釋放A上的鎖。這保證了其他事務在事物 1 釋放A上的鎖之前不能再讀取和修改A。排它鎖會阻塞所有的排它鎖和共享鎖

讀取為什么要加讀鎖呢:防止數據在被讀取的時候被別的線程加上寫鎖,

使用方式:在需要執行的語句后面加上for update就可以了

行鎖

行鎖又分共享鎖排他鎖,由字面意思理解,就是給某一行加上鎖,也就是一條記錄加上鎖。

注意:行級鎖都是基于索引的,如果一條SQL語句用不到索引是不會使用行級鎖的,會使用表級鎖。

共享鎖:

名詞解釋:共享鎖又叫做讀鎖,所有的事務只能對其進行讀操作不能寫操作,加上共享鎖后在事務結束之前其他事務只能再加共享鎖,除此之外其他任何類型的鎖都不能再加了。

SELECT * from TABLE where id = "1"  lock in share mode;  結果集的數據都會加共享鎖

排他鎖:

名詞解釋:若某個事物對某一行加上了排他鎖,只能這個事務對其進行讀寫,在此事務結束之前,其他事務不能對其進行加任何鎖,其他進程可以讀取,不能進行寫操作,需等待其釋放。

select status from TABLE where id=1 for update;

可以參考之前演示的共享鎖,排它鎖語句

由于對于表中,id字段為主鍵,就也相當于索引。執行加鎖時,會將id這個索引為1的記錄加上鎖,那么這個鎖就是行鎖。

表鎖

如何加表鎖

innodb 的行鎖是在有索引的情況下,沒有索引的表是鎖定全表的.

Innodb中的行鎖與表鎖

前面提到過,在Innodb引擎中既支持行鎖也支持表鎖,那么什么時候會鎖住整張表,什么時候或只鎖住一行呢?
只有通過索引條件檢索數據,InnoDB才使用行級鎖,否則,InnoDB將使用表鎖!

在實際應用中,要特別注意InnoDB行鎖的這一特性,不然的話,可能導致大量的鎖沖突,從而影響并發性能。

行級鎖都是基于索引的,如果一條SQL語句用不到索引是不會使用行級鎖的,會使用表級鎖。行級鎖的缺點是:由于需要請求大量的鎖資源,所以速度慢,內存消耗大。

死鎖

死鎖(Deadlock)
所謂死鎖:是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。此時稱系統處于死鎖狀態或系統產生了死鎖,這些永遠在互相等待的進程稱為死鎖進程。由于資源占用是互斥的,當某個進程提出申請資源后,使得有關進程在無外力協助下,永遠分配不到必需的資源而無法繼續運行,這就產生了一種特殊現象死鎖。

解除正在死鎖的狀態有兩種方法:

第一種

1.查詢是否鎖表

show OPEN TABLES where In_use > 0;

2.查詢進程(如果您有SUPER權限,您可以看到所有線程。否則,您只能看到您自己的線程)

show processlist

3.殺死進程id(就是上面命令的id列)

kill id

第二種

1:查看當前的事務

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

2:查看當前鎖定的事務

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

3:查看當前等鎖的事務

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

殺死進程

kill 線程ID

如果系統資源充足,進程的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,進程運行推進順序與速度不同,也可能產生死鎖。
產生死鎖的四個必要條件:

(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。

雖然不能完全避免死鎖,但可以使死鎖的數量減至最少。將死鎖減至最少可以增加事務的吞吐量并減少系統開銷,因為只有很少的事務回滾,而回滾會取消事務執行的所有工作。由于死鎖時回滾而由應用程序重新提交。

下列方法有助于最大限度地降低死鎖:

(1)按同一順序訪問對象。
(2)避免事務中的用戶交互。
(3)保持事務簡短并在一個批處理中。
(4)使用低隔離級別。
(5)使用綁定連接。

end!

相關文章:

數據庫并發事務控制 二:mysql數據庫鎖機制

Mysql數據庫鎖定機制詳細介紹

相關視頻:

數據庫設計那些事

以上就是數據庫高并發請求,如何保證數據完整性?詳解MySQL/InnoDB的加鎖的詳細內容,更多請關注php中文網其它相關文章!


學習教程快速掌握從入門到精通的SQL知識。




主站蜘蛛池模板: 亚洲精品在线不卡 | 热99精品视频 | 日韩在线2020专区 | 天天色踪合 | 欧美视频第一页 | 色在线导航 | 欧美又大粗又爽又黄大片视频黑人 | 日日操夜夜操免费视频 | 色综合久久六月婷婷中文字幕 | 性欧美巨大极品videos | 一国产一级淫片a免费播放口 | 色噜噜在线 | 天天天天天天天操 | 日韩欧美高清在线 | 亚洲福利影院 | 日本免费高清视频 | 午夜国产精品久久影院 | 伊人官网 | 香蕉www| 婷婷久久综合九色综合九七 | 亚州一级毛片在线 | 亚洲午夜高清 | 在线观看亚洲 | 性刺激性色爽爱小说 | 五月网婷婷| 四虎国产精品免费观看 | 色在线播放 | 人人狠狠| 全黄性色大片 | 日韩欧美中文 | 香蕉91| 亚洲不卡中文字幕 | 日韩诱惑| 日韩在线视频播放 | 四虎最新网站 | 欧美性猛交xxxx乱大交 | 一级毛片一片毛 | 亚洲一区二区三区四区在线 | 亚洲第一区在线 | 青青草免费线观 | 欧美性视屏 |