自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一致性非鎖定讀與一致性鎖定讀

運維 數(shù)據(jù)庫運維
一致性非鎖定讀講的是一條記錄被加了X鎖其他事務仍然可以讀而不被阻塞,是通過innodb的行多版本實現(xiàn)的,行多版本并不是實際存儲多個版本記錄而是通過undo實現(xiàn)。一致性鎖定讀講的是我可以通過SELECT語句顯式地給一條記錄加X鎖從而保證特定應用場景下的數(shù)據(jù)一致性。

背景

innodb存儲引擎實現(xiàn)了兩種標準的行級鎖:S鎖和X鎖,S鎖被稱為共享鎖,允許事務讀一行數(shù)據(jù),X鎖被稱為排它鎖,允許事務刪除或更新一行數(shù)據(jù)。

一致性非鎖定讀指的是如果一條記錄被加了X鎖,其他事務還能讀取這條記錄。

一致性鎖定讀指的是一個事務可以通過SELECT語句給某條記錄加X鎖或者X鎖。

一個小栗子

我們假設有一個表和兩個事務,表名字為mytest,事務名字為t1和t2:

t1 t2 t3 t4
a bb bb ccc

t1和t2的執(zhí)行時序如下: 

 

這里我先拋出兩個問題:

  • 上面Mark A處顯然t1已經(jīng)給記錄加了X鎖,并且在事務內(nèi)修改了數(shù)據(jù),此時t2看到的數(shù)據(jù)是什么?
  • 上面Mark B處事務t1已經(jīng)提交此時t2看到的數(shù)據(jù)是什么?

行多版本控制

行多版本將的是innodb為每個行記錄存儲了多個版本,記住,這里是多個版本不是兩個版本,在剛開始接觸多版本的時候,我的疑問是innodb對每個行要存儲多個版本是多么浪費存儲空間呀?然而進一步了解,原來所謂的多版本只是innodb聰明地撒了個謊,多個版本是通過undo日志實現(xiàn)的,這里可以理解為既然undo日志包括了所有用來恢復歷史版本數(shù)據(jù)的信息,那么我們只要將“不同版本”指針指向不同時間節(jié)點的undo日志即可,這樣讀取的時候通過對不同時間節(jié)點的undo日志進行恢復從而得到不同的版本數(shù)據(jù)。同時對于undo日志的讀取是不需要加鎖的,因此這極大地提高了數(shù)據(jù)庫的并發(fā)性。

這里回答了上面的***個問題:t2此時看到的應該是歷史版本的數(shù)據(jù),也就是t1修改之前的數(shù)據(jù),如下:

  1. mysql> select * from mytest where t2='bb'
  2.  
  3. +------+------+------+------+ 
  4.  
  5. | t1 | t2 | t3 | t4 | 
  6.  
  7. +------+------+------+------+ 
  8.  
  9. | a | bb | bb | ccc | 
  10.  
  11. +------+------+------+------+ 
  12.  
  13. 1 row in set (0.00 sec) 
  14.  
  15. READ COMMITTED 與 REPEATABLE READ  

這里復習一下SQL標準定義的四個隔離級別分別為:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

innodb默認的隔離級別為REPEATABLE READ且使用next key locking技術解決的幻讀的問題,READ COMMITTED值的是一個事務可以讀取其他事務已經(jīng)提交的數(shù)據(jù),而REPEATABLE READ要求一個事務在事務內(nèi)可以重復讀取一條記錄,因此上面第二個問題的答案是此時t2看到的是什么跟此時數(shù)據(jù)庫的隔離級別有關系,比如此時的隔離級別為:

  1. mysql> select @@tx_isolation; 
  2.  
  3. +-----------------+ 
  4.  
  5. | @@tx_isolation | 
  6.  
  7. +-----------------+ 
  8.  
  9. REPEATABLE-READ | 
  10.  
  11. +-----------------+ 
  12.  
  13. 1 row in set (0.00 sec)  

因此t2在Mark B的地方看到的應該是老數(shù)據(jù):

  1. mysql> select * from mytest where t2='bb'
  2.  
  3. +------+------+------+------+ 
  4.  
  5. | t1 | t2 | t3 | t4 | 
  6.  
  7. +------+------+------+------+ 
  8.  
  9. | a | bb | bb | ccc | 
  10.  
  11. +------+------+------+------+ 
  12.  
  13. 1 row in set (0.00 sec) 
  14.  
  15. mysql>  

如果此時的事務隔離級別為READ COMMITTED,則t2在Mark B處看到的應該是新數(shù)據(jù)。

一致性鎖定讀

一致性非鎖定讀的情況下即使記錄因為UPDATE而被加了X鎖,其他事務仍然能夠讀取記錄,不會阻塞。而如果一個事務希望在讀取的時候就把記錄鎖住,不允許其他事務進行修改應該怎么做呢?那就是SELECT … FOR UPDATE,SELECT … FOR UPDATE顯式地給一條記錄加X鎖,因此其他事務不能獲取該記錄的任何鎖。我們也可以使用SELECT … LOCK IN SHARE MODE來給記錄顯式地加S鎖,因此其他事務能夠獲取該記錄的S鎖而不能獲取該記錄的X鎖,這兩種語句都是有特定的應用場景的。

總結

再總結一下,一致性非鎖定讀講的是一條記錄被加了X鎖其他事務仍然可以讀而不被阻塞,是通過innodb的行多版本實現(xiàn)的,行多版本并不是實際存儲多個版本記錄而是通過undo實現(xiàn)。一致性鎖定讀講的是我可以通過SELECT語句顯式地給一條記錄加X鎖從而保證特定應用場景下的數(shù)據(jù)一致性。 

責任編輯:龐桂玉 來源: 數(shù)據(jù)庫開發(fā)
相關推薦

2020-11-24 09:03:41

一致性MySQLMVCC

2020-09-10 10:26:44

MySQL數(shù)據(jù)庫MVCC

2011-05-04 10:19:13

MVCC

2011-05-04 09:43:23

當前模式讀一致性讀

2022-12-14 08:23:30

2021-02-05 08:00:48

哈希算法?機器

2021-02-02 12:40:50

哈希算法數(shù)據(jù)

2021-06-22 10:22:08

業(yè)務IT一致性首席信息官

2016-12-19 18:41:09

哈希算法Java數(shù)據(jù)

2020-05-12 10:43:22

Redis緩存數(shù)據(jù)庫

2022-03-22 09:54:22

Hash算法

2022-10-19 12:22:53

并發(fā)扣款一致性

2021-06-30 21:13:49

CPUCache數(shù)據(jù)

2021-02-04 06:30:26

Python編程語言

2016-11-16 19:15:34

消息時序分布式系統(tǒng)

2022-11-10 07:49:09

hash算法代碼

2019-10-11 23:27:19

分布式一致性算法開發(fā)

2017-07-02 16:28:06

MySQL數(shù)據(jù)庫集群

2017-05-19 15:00:05

session架構web-server

2020-03-16 11:55:28

PaxosRaft協(xié)議
點贊
收藏

51CTO技術棧公眾號