偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我說MySQL里每張表不要超過100w數(shù)據(jù),面試官讓我回去等通知?

數(shù)據(jù)庫 MySQL
就是說事務(wù)A在跑的時(shí)候, 先查詢了一個(gè)數(shù)據(jù)是值1,然后過了段時(shí)間,事務(wù)B把那個(gè)數(shù)據(jù)給修改了一下還提交了,此時(shí)事務(wù)A再次查詢這個(gè)數(shù)據(jù)就成了值2了,這是讀了人家事務(wù)提交的數(shù)據(jù)啊,所以是讀已提交。

1、面試題

  • 事務(wù)的幾個(gè)特點(diǎn)是什么?
  • 數(shù)據(jù)庫事務(wù)有哪些隔離級(jí)別?
  • MySQL的默認(rèn)隔離級(jí)別?

2、面試官心里分析

用mysql開發(fā)的三個(gè)基本面:存儲(chǔ)引擎、索引,然后就是事務(wù),你必須得用事務(wù)。

因?yàn)橐粋€(gè)業(yè)務(wù)系統(tǒng)里,肯定要加事務(wù)保證一堆關(guān)聯(lián)操作,要么一起成功要么一起失敗,對(duì)不對(duì)?所以這是聊數(shù)據(jù)庫必問的一個(gè)問題

最最最基本的用mysql來開發(fā),就3點(diǎn):存儲(chǔ)引擎(了解),索引(能建索引,寫的SQL都用上索引),事務(wù)(了解事務(wù)的隔離級(jí)別,基于spring的事務(wù)支持在代碼里加事務(wù))

存儲(chǔ)引擎 -> innodb,索引,基本按照你的SQL的需求都建了索引(可能漏了部分索引忘了建),事務(wù)(@Transactional注解,對(duì)service層統(tǒng)一加了事務(wù))

3、面試題剖析

3.1 事務(wù)的ACID

這個(gè)先說一下ACID,必須得知道:

(1)Atomic:原子性,就是一堆SQL,要么一起成功,要么都別執(zhí)行,不允許某個(gè)SQL成功了,某個(gè)SQL失敗了,這就是扯淡,不是原子性。

(2)Consistency:一致性,這個(gè)是針對(duì)數(shù)據(jù)一致性來說的,就是一組SQL執(zhí)行之前,數(shù)據(jù)必須是準(zhǔn)確的,執(zhí)行之后,數(shù)據(jù)也必須是準(zhǔn)確的。別搞了半天,執(zhí)行完了SQL,結(jié)果SQL對(duì)應(yīng)的數(shù)據(jù)修改沒給你執(zhí)行,那不是坑爹么。

(3)Isolation:隔離性,這個(gè)就是說多個(gè)事務(wù)在跑的時(shí)候不能互相干擾,別事務(wù)A操作個(gè)數(shù)據(jù),弄到一半兒還沒弄好呢,結(jié)果事務(wù)B來改了這個(gè)數(shù)據(jù),導(dǎo)致事務(wù)A的操作出錯(cuò)了,那不就搞笑了。

(4)Durability:持久性,事務(wù)成功了,就必須永久對(duì)數(shù)據(jù)的修改是有效的,別過了一會(huì)兒數(shù)據(jù)自己沒了,不見了,那就好玩兒了。

3.2 事務(wù)隔離級(jí)別

總之,面試問你事務(wù),先聊一下ACID,然后聊聊隔離級(jí)別

(1)讀未提交,Read Uncommitted:這個(gè)很坑爹,就是說某個(gè)事務(wù)還沒提交的時(shí)候,修改的數(shù)據(jù),就讓別的事務(wù)給讀到了,這就惡心了,很容易導(dǎo)致出錯(cuò)的。這個(gè)也叫做臟讀。

(2)讀已提交,Read Committed(不可重復(fù)讀):這個(gè)比上面那個(gè)稍微好一點(diǎn),但是一樣比較尷尬

就是說事務(wù)A在跑的時(shí)候, 先查詢了一個(gè)數(shù)據(jù)是值1,然后過了段時(shí)間,事務(wù)B把那個(gè)數(shù)據(jù)給修改了一下還提交了,此時(shí)事務(wù)A再次查詢這個(gè)數(shù)據(jù)就成了值2了,這是讀了人家事務(wù)提交的數(shù)據(jù)啊,所以是讀已提交。

這個(gè)也叫做不可重復(fù)讀,就是所謂的一個(gè)事務(wù)內(nèi)對(duì)一個(gè)數(shù)據(jù)兩次讀,可能會(huì)讀到不一樣的值。如圖:

(3)可重復(fù)讀,Read Repeatable:這個(gè)比上面那個(gè)再好點(diǎn)兒,就是說事務(wù)A在執(zhí)行過程中,對(duì)某個(gè)數(shù)據(jù)的值,無論讀多少次都是值1;哪怕這個(gè)過程中事務(wù)B修改了數(shù)據(jù)的值還提交了,但是事務(wù)A讀到的還是自己事務(wù)開始時(shí)這個(gè)數(shù)據(jù)的值。如圖:

(4)幻讀:不可重復(fù)讀和可重復(fù)讀都是針對(duì)兩個(gè)事務(wù)同時(shí)對(duì)某條數(shù)據(jù)在修改,但是幻讀針對(duì)的是插入

比如某個(gè)事務(wù)把所有行的某個(gè)字段都修改為了2,結(jié)果另外一個(gè)事務(wù)插入了一條數(shù)據(jù),那個(gè)字段的值是1,然后就尷尬了。第一個(gè)事務(wù)會(huì)突然發(fā)現(xiàn)多出來一條數(shù)據(jù),那個(gè)數(shù)據(jù)的字段是1。

那么幻讀會(huì)帶來啥問題呢?因?yàn)樵诖烁綦x級(jí)別下,例如:事務(wù)1要插入一條數(shù)據(jù),我先查詢一下有沒有相同的數(shù)據(jù),但是這時(shí)事務(wù)2添加了這條數(shù)據(jù),這就會(huì)導(dǎo)致事務(wù)1插入失敗,并且它就算再一次查詢,也無法查詢到與其插入相沖突的數(shù)據(jù),同時(shí)自身死活都插入不了,這就不是尷尬,而是囧了。

(5)串行化:如果要解決幻讀,就需要使用串行化級(jí)別的隔離級(jí)別,所有事務(wù)都串行起來,不允許多個(gè)事務(wù)并行操作。如圖:

(6)MySQL的默認(rèn)隔離級(jí)別是Read Repeatable,就是可重復(fù)讀,就是說每個(gè)事務(wù)都會(huì)開啟一個(gè)自己要操作的某個(gè)數(shù)據(jù)的快照,事務(wù)期間,讀到的都是這個(gè)數(shù)據(jù)的快照罷了,對(duì)一個(gè)數(shù)據(jù)的多次讀都是一樣的。

接下來我們聊下MySQL是如何實(shí)現(xiàn)Read Repeatable的吧,因?yàn)橐话阄覀兌疾恍薷倪@個(gè)隔離級(jí)別,但是你得清楚是怎么回事兒,MySQL是通過MVCC機(jī)制來實(shí)現(xiàn)的,就是多版本并發(fā)控制,multi-version concurrency control。

當(dāng)我們使用innodb存儲(chǔ)引擎,會(huì)在每行數(shù)據(jù)的最后加兩個(gè)隱藏列,一個(gè)保存行的創(chuàng)建時(shí)間,一個(gè)保存行的刪除時(shí)間,但是這兒存放的不是時(shí)間,而是事務(wù)id,事務(wù)id是mysql自己維護(hù)的自增的,全局唯一。

事務(wù)id,在mysql內(nèi)部是全局唯一遞增的,事務(wù)id=1,事務(wù)id=2,事務(wù)id=3


事務(wù)id=121的事務(wù),查詢id=1的這一行的時(shí)候,一定會(huì)找到創(chuàng)建事務(wù)id <= 當(dāng)前事務(wù)id的那一行

select * from table where id=1,就可以查到上面那一行

事務(wù)id=122的事務(wù),將id=1的這一行給刪除了,此時(shí)就會(huì)將id=1的行的刪除事務(wù)id設(shè)置成122

事務(wù)id=121的事務(wù),再次查詢id=1的那一行,能查到嗎?

能查到,要求創(chuàng)建事務(wù)id <= 當(dāng)前事務(wù)id,當(dāng)前事務(wù)id < 刪除事務(wù)id

事務(wù)id=121的事務(wù),查詢id=2的那一行,查到name=李四

事務(wù)id=122的事務(wù),將id=2的那一行的name修改成name=小李四

事務(wù)id=121的事務(wù),查詢id=2的那一行,答案是:李四,創(chuàng)建事務(wù)id <= 當(dāng)前事務(wù)id,當(dāng)前事務(wù)id < 刪除事務(wù)id

在一個(gè)事務(wù)內(nèi)查詢的時(shí)候,mysql只會(huì)查詢創(chuàng)建時(shí)間的事務(wù)id小于等于當(dāng)前事務(wù)id的行,這樣可以確保這個(gè)行是在當(dāng)前事務(wù)中創(chuàng)建,或者是之前創(chuàng)建的;

同時(shí)一個(gè)行的刪除時(shí)間的事務(wù)id要么沒有定義(就是沒刪除),要么是必當(dāng)前事務(wù)id大(在事務(wù)開啟之后才被刪除);滿足這兩個(gè)條件的數(shù)據(jù)都會(huì)被查出來。

那么如果某個(gè)事務(wù)執(zhí)行期間,別的事務(wù)更新了一條數(shù)據(jù)呢?這個(gè)很關(guān)鍵的一個(gè)實(shí)現(xiàn),其實(shí)就是在innodb中,是插入了一行記錄,然后將新插入的記錄的創(chuàng)建時(shí)間設(shè)置為新的事務(wù)的id,同時(shí)將這條記錄之前的那個(gè)版本的刪除時(shí)間設(shè)置為新的事務(wù)的id。

現(xiàn)在get到這個(gè)點(diǎn)了吧?這樣的話,你的這個(gè)事務(wù)其實(shí)對(duì)某行記錄的查詢,始終都是查找的之前的那個(gè)快照,因?yàn)橹暗哪莻€(gè)快照的創(chuàng)建時(shí)間小于等于自己事務(wù)id,然后刪除時(shí)間的事務(wù)id比自己事務(wù)id大,所以這個(gè)事務(wù)運(yùn)行期間,會(huì)一直讀取到這條數(shù)據(jù)的同一個(gè)版本。

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2024-02-26 12:38:21

MySQLInnoDB跨度

2024-08-05 01:26:54

2022-11-15 17:45:46

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

2021-02-06 09:21:17

MySQL索引面試

2024-09-05 21:24:02

數(shù)據(jù)庫查詢MySQLlimit

2022-12-06 09:03:31

MySQL索引

2024-08-21 10:28:54

Redis數(shù)據(jù)結(jié)構(gòu)內(nèi)存

2020-12-16 08:05:54

Mybatis面試動(dòng)態(tài)代理

2022-10-31 08:29:37

MySQL單表參數(shù)

2021-12-02 08:19:06

MVCC面試數(shù)據(jù)庫

2020-05-22 08:11:48

線程池JVM面試

2022-07-13 17:47:54

布局Flex代碼

2025-02-13 00:00:00

TCP網(wǎng)絡(luò)通信

2019-08-23 09:03:04

盤口數(shù)據(jù)數(shù)據(jù)庫緩存

2020-09-17 17:53:12

面試ArrayList數(shù)組

2020-07-02 07:52:11

RedisHash映射

2025-03-12 00:52:00

Java樂觀鎖悲觀鎖

2020-08-13 10:15:34

MySQL數(shù)據(jù)庫面試

2022-02-11 19:06:29

MySQL索引面試官

2021-03-01 18:42:02

緩存LRU算法
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)