**1\. 什么是事務?**
理解什么是事務最經典的就是轉賬的例子,相信大家也都了解,這里就不再說一邊了.
事務是一系列的操作,他們要符合ACID特性.最常見的理解就是:事務中的操作要么全部成功,要么全部失敗.但是只是這樣還不夠的.
*****
**2\. ACID是什么?可以詳細說一下嗎?**
A=Atomicity
原子性,就是上面說的,要么全部成功,要么全部失敗.不可能只執行一部分操作.
C=Consistency
系統(數據庫)總是從一個一致性的狀態轉移到另一個一致性的狀態,不會存在中間狀態.
I=Isolation
隔離性: 通常來說:一個事務在完全提交之前,對其他事務是不可見的.注意前面的通常來說加了紅色,意味著有例外情況.
D=Durability
持久性,一旦事務提交,那么就永遠是這樣子了,哪怕系統崩潰也不會影響到這個事務的結果.
*****
**3\. 同時有多個事務在進行會怎么樣呢?**
多事務的并發進行一般會造成以下幾個問題:
* 臟讀: A事務讀取到了B事務未提交的內容,而B事務后面進行了回滾.
* 不可重復讀: 當設置A事務只能讀取B事務已經提交的部分,會造成在A事務內的兩次查詢,結果竟然不一樣,因為在此期間B事務進行了提交操作.
* 幻讀: A事務讀取了一個范圍的內容,而同時B事務在此期間插入了一條數據.造成"幻覺".
*****
**4\. 怎么解決這些問題呢?MySQL的事務隔離級別了解嗎?**
MySQL的四種隔離級別如下:
* 未提交讀(READ UNCOMMITTED)
這就是上面所說的例外情況了,這個隔離級別下,其他事務可以看到本事務沒有提交的部分修改.因此會造成臟讀的問題(讀取到了其他事務未提交的部分,而之后該事務進行了回滾).
這個級別的性能沒有足夠大的優勢,但是又有很多的問題,因此很少使用.
* 已提交讀(READ COMMITTED)
其他事務只能讀取到本事務已經提交的部分.這個隔離級別有 不可重復讀的問題,在同一個事務內的兩次讀取,拿到的結果竟然不一樣,因為另外一個事務對數據進行了修改.
* REPEATABLE READ(可重復讀)
可重復讀隔離級別解決了上面不可重復讀的問題(看名字也知道),但是仍然有一個新問題,就是 幻讀,當你讀取id> 10 的數據行時,對涉及到的所有行加上了讀鎖,此時例外一個事務新插入了一條id=11的數據,因為是新插入的,所以不會觸發上面的鎖的排斥,那么進行本事務進行下一次的查詢時會發現有一條id=11的數據,而上次的查詢操作并沒有獲取到,再進行插入就會有主鍵沖突的問題.
* SERIALIZABLE(可串行化)
這是最高的隔離級別,可以解決上面提到的所有問題,因為他強制將所以的操作串行執行,這會導致并發性能極速下降,因此也不是很常用.
*****
**5\. Innodb使用的是哪種隔離級別呢?**
InnoDB默認使用的是可重復讀隔離級別.
*****
**6\. 對MySQL的鎖了解嗎?**
當數據庫有并發事務的時候,可能會產生數據的不一致,這時候需要一些機制來保證訪問的次序,鎖機制就是這樣的一個機制.
就像酒店的房間,如果大家隨意進出,就會出現多人搶奪同一個房間的情況,而在房間上裝上鎖,申請到鑰匙的人才可以入住并且將房間鎖起來,其他人只有等他使用完畢才可以再次使用.
*****
**7\. MySQL都有哪些鎖呢?像上面那樣子進行鎖定豈不是有點阻礙并發效率了?**
*****
從鎖的類別上來講,有共享鎖和排他鎖.
共享鎖: 又叫做讀鎖. 當用戶要進行數據的讀取時,對數據加上共享鎖.共享鎖可以同時加上多個.
排他鎖: 又叫做寫鎖. 當用戶要進行數據的寫入時,對數據加上排他鎖.排他鎖只可以加一個,他和其他的排他鎖,共享鎖都相斥.
用上面的例子來說就是用戶的行為有兩種,一種是來看房,多個用戶一起看房是可以接受的. 一種是真正的入住一晚,在這期間,無論是想入住的還是想看房的都不可以.
鎖的粒度取決于具體的存儲引擎
他們的加鎖開銷從大大小,并發能力也是從大到小.