1. 程式人生 > >資料庫樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖概念的理解

資料庫樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖概念的理解

實驗環境:

mysql5.6

儲存引擎:innoDB

我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突)

樂觀鎖

樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否有衝突了。

通常實現是這樣的:在表中的資料進行操作時(更新),先給資料表加一個版本(version)欄位,每操作一次,將那條記錄的版本號加1。也就是先查詢出那條記錄,獲取出version欄位,如果要對那條記錄進行操作(更新),則先判斷此刻version的值是否與剛剛查詢出來時的version的值相等,如果相等,則說明這段期間,沒有其他程式對其進行操作,則可以執行更新,將version欄位的值加1;如果更新時發現此刻的version值與剛剛獲取出來的version的值不相等,則說明這段期間已經有其他程式對其進行操作了,則不進行更新操作。

舉例:

下單操作包括3步驟:

1.查詢出商品資訊

select (status,status,version) from t_goods where id=#{id}

2.根據商品資訊生成訂單

3.修改商品status為2

update t_goods 

set status=2,version=version+1

where id=#{id} and version=#{version};

除了自己手動實現樂觀鎖之外,現在網上許多框架已經封裝好了樂觀鎖的實現,如hibernate,需要時,可能自行搜尋"hiberate 樂觀鎖"試試看。


悲觀鎖

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

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

共享鎖

共享鎖指的就是對於多個不同的事務,對同一個資源共享同一個鎖。相當於對於同一把門,它擁有多個鑰匙一樣。就像這樣,你家有一個大門,大門的鑰匙有好幾把,你有一把,你女朋友有一把,你們都可能通過這把鑰匙進入你們家,一下理解了哈,沒錯,這個就是所謂的共享鎖。剛剛說了,對於悲觀鎖,一般資料庫已經實現了,共享鎖也屬於悲觀鎖的一種,那麼共享鎖在mysql中是通過什麼命令來呼叫呢。通過查詢資料,瞭解到通過在執行語句後面加上lock in share mode就代表對某些資源加上共享鎖了。比如,我這裡通過mysql開啟兩個查詢編輯器,在其中開啟一個事務,並不執行commit語句city表DDL如下:
  1. CREATE TABLE `city` (  
  2.   `id` bigint(20) NOT NULL AUTO_INCREMENT,  
  3.   `name` varchar(255) DEFAULT NULL,  
  4.   `state` varchar(255) DEFAULT NULL,  
  5.   PRIMARY KEY (`id`)  
  6. ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;  


begin;
SELECT * from city where id = "1"  lock in share mode;
然後在另一個查詢視窗中,對id為1的資料進行更新
update  city set name="666" where id ="1";
此時,操作介面進入了卡頓狀態,過幾秒後,也提示錯誤資訊[SQL]update  city set name="666" where id ="1";
[Err] 1205 - Lock wait timeout exceeded; try restarting transaction

那麼證明,對於id=1的記錄加鎖成功了,在上一條記錄還沒有commit之前,這條id=1的記錄被鎖住了,只有在上一個事務釋放掉鎖後才能進行操作,或用共享鎖才能對此資料進行操作。再實驗一下:
update city set name="666" 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
加上共享鎖後,也提示錯誤資訊了,通過查詢資料才知道,對於update,insert,delete語句會自動加排它鎖的原因於是,我又試了試SELECT * from city where id = "1" lock in share mode;
這下成功了。

排它鎖

排它鎖與共享鎖相對應,就是指對於多個不同的事務,對同一個資源只能有一把鎖。與共享鎖型別,在需要執行的語句後面加上for update就可以了

行鎖

行鎖,由字面意思理解,就是給某一行加上鎖,也就是一條記錄加上鎖。

比如之前演示的共享鎖語句

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

由於對於city表中,id欄位為主鍵,就也相當於索引。執行加鎖時,會將id這個索引為1的記錄加上鎖,那麼這個鎖就是行鎖。

表鎖

表鎖,和行鎖相對應,給這個表加上鎖。

MyISAM引擎裡有的,暫時研究了

相關推薦

資料庫樂觀悲觀共享理解

mysql5.6 我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何其他的特殊處理(也就

資料庫樂觀悲觀共享概念理解

實驗環境:mysql5.6儲存引擎:innoDB我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突)樂觀鎖樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何

樂觀悲觀共享以及概念

樂觀鎖 樂觀併發控制(又名”樂觀鎖”,Optimistic Concurrency Control,縮寫”OCC”),它假設多使用者併發的事務在處理時不會彼此互相影響,各事務能夠在不產生鎖的情況下處理各自影響的那部分資料。在提交資料更新之前,每個事務會先檢查在該事務讀取資料後,有沒有其他事務

最簡單理解Mysql共享排他樂觀悲觀

共享鎖 select * from xx where id = 10 lock in share mode 排他鎖 select * from xx where id = 10 for update 樂觀鎖 select num,version from xx where id = 10

mysql樂觀悲觀共享

我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在操作資料時,並不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否

對mysql樂觀悲觀共享概念理解

實驗環境: mysql5.6 儲存引擎:innoDB 我們在操作資料庫的時候,可能會由於併發問題而引起的資料的不一致性(資料衝突) 樂觀鎖 樂觀鎖不是資料庫自帶的,需要我們自己去實現。樂觀鎖是指操作資料庫時(更新操作),想法很樂觀,認為這次的操作不會導致衝突,在

MySQL中樂觀悲觀共享概念

樂觀鎖 樂觀鎖是指在操作資料庫時(更新操作),想法很樂觀,認為此次操作不會導致衝突,所以在操作資料時,不進行任何其他的特殊處理(也就是不加鎖),而在進行更新後,再去判斷是否有衝突。 悲觀鎖 悲觀鎖是指在操作資料庫時(更新操作),想法很悲觀,認為此次操作會出現衝突,所以在

MySQL/InnoDB中,樂觀悲觀共享概念理解

MySQL/InnoDB的加鎖,一直是一個面試中常問的話題。例如,資料庫如果有高併發請求,如何保證資料完整性?產生死鎖問題如何排查並解決?我在工作過程中,也會經常用到,樂觀鎖,排它鎖,等。於是今天就對這幾個概念進行學習,屢屢思路,記錄一下。 注:MySQL是一

Mysql共享排他悲觀樂觀及其使用場景

一、相關名詞 |--表級鎖(鎖定整個表) |--頁級鎖(鎖定一頁) |--行級鎖(鎖定一行) |--共享鎖(S鎖,MyISAM 叫做讀鎖) |--排他鎖(X鎖,MyISAM 叫做寫鎖) |--悲觀鎖(抽象性,不真實存在這個鎖) |--樂觀鎖(抽象性,不真實存在這個鎖) 二

對於Zookeeper中提及的共享悲觀樂觀理解

排它鎖 (簡稱X鎖),又稱為寫鎖或獨佔鎖,是一種基本的鎖型別。如果事務T1對資料物件O1加上了排它鎖,那麼在整個加鎖期間,只允許事務T1對O1進行讀取和更新操作,其它任何事務都幫你再對這個資料物件進行任何型別的操作,——直到T1釋放了排它鎖。 從上邊講解的排

MySQL中的樂觀悲觀共享概念

下文的所有介紹,都是基於InnoDB儲存引擎,其他引擎的表現,會有較大的區別。 樂觀鎖 用資料版本(Version)記錄機制實現,是樂觀鎖最常用的一種實現方式。什麼是資料版本?即為資料增加一個版本標識,一般是通過為資料庫表增加一個數字型別的“version”欄位來實現

對mysql樂觀悲觀共享概念理解 (轉)

而在 狀態 line 主鍵 n) efault 你家 不一致 開啟 實驗環境: mysql5.6 存儲引擎:innoDB 我們在操作數據庫的時候,可能會由於並發問題而引起的數據的不一致性(數據沖突) 樂觀鎖樂觀鎖不是數據庫自帶的,需要我們自己去實現。樂觀鎖是指操作數據庫

資料庫中的樂觀悲觀

樂觀鎖、悲觀鎖:http://blog.csdn.net/hongchangfirst/article/details/26004335 行鎖、表鎖:http://blog.sina.com.cn/s/blog_703074da0101ghsh.html

資料庫機制--悲觀樂觀)與

上一章講到了資料庫事務的隔離級別以及併發事務在不同隔離級別下可能帶來的問題和解決思路,感興趣的朋友可以看一下!直接切入正題:      從字面上看,行級鎖的作用範圍肯定比表級鎖的作用範圍要小;行級鎖和表級鎖是根據鎖的粒度來區分的,行記錄,表都是資源,鎖是作用在這些資源上的。如

JAVA樂觀悲觀實現

個數 自動 時間 update 頻繁 每次 調用 內部實現 字段 一、名詞解釋   1、悲觀鎖:認為每次對數據庫的操作(查詢、修改)都是不安全的,因此每次操作都會把這條數據鎖掉,直到本次操作完畢釋放該鎖   2、樂觀鎖:查詢數據的時候總是認為是安全的,不會鎖數據;等到更新數

MySQL-----樂觀悲觀

數據庫操作 重要 讀寫 收購 線程並發 串行化 之前 並發執行 引擎 回顧: ACID:DBMS在寫入或更新資料的過程中,為保證事務正確可靠,具有的四個特性:原子性(不可分割性)、一致性、隔離性(獨立性)、持久性 一個事務:一系列數據庫操作組成的一個完整的邏輯過程 原子性:

mysql 悲觀共享

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

死磕java concurrent包系列(一)從樂觀悲觀到AtomicInteger的CAS演算法

前言 Java中有各式各樣的鎖,主流的鎖和概念如下: 這篇文章主要是為了讓大家通過樂觀鎖和悲觀鎖出發,理解CAS演算法,因為CAS是整個Concurrent包的基礎。 樂觀鎖和悲觀鎖 首先,java和資料庫中都有這種概念,他是一種從執行緒同步的角度上看的一種廣義上的概念: 悲觀鎖:悲觀的認為自己在使用資料的

淺析樂觀悲觀與CAS

樂觀鎖與悲觀鎖 處理多執行緒併發訪問最常用的就是加鎖,鎖又分成樂觀鎖和悲觀鎖。 悲觀鎖 在多執行緒訪問共享資源時,同時只允許一個執行緒獨享此資源,其他執行緒都被悲觀鎖阻塞,只有當前擁有鎖的執行緒釋放鎖,其他執行緒才能被喚起競爭這個資源,每個執行緒在獲取資源前都要

python之Django的入門08------事務管理悲觀樂觀

我們接著上一篇文章的基礎上,來繼續瞭解進一步的Django框架 一.事務管理 在實際專案裡,事務管理是一個很重要的內容。 他可以保證一系列類操作要不全部成功要不全部失敗。也可以保證當多個應用程式在併發訪問資料庫時,可以在這些應用程式之間提供一個隔離方法,以防止