1. 程式人生 > >java面試-資料庫事務詳解

java面試-資料庫事務詳解

什麼是『事務』?

事務就是一組具有原子性的操作,這一組操作要麼全都正確執行,要麼全都不執行。 
事務能保證資料庫從一種一致性狀態轉換為另一種一致性狀態。

事務的四大特性ACID

1. 原子性

原子性指的是事務是一個不可分割的操作,要麼全都正確執行,要麼全都不執行。

2. 一致性

事務開始前和事務結束後,資料庫的完整性約束沒有被破壞。

3. 隔離性

事務的執行是相互獨立的,它們不會相互干擾,一個事務不會看到另一個正在執行過程中的事務的資料。

4. 永續性

事務結束後,事務的結果必須是永久儲存的。即使資料庫發生崩潰,在資料庫恢復後事務提交的結果仍然不會丟失。 
PS:事務只能保證資料庫的高可靠性,即資料庫本身發生問題後,事務提交後的資料仍然能恢復;而如果不是資料庫本身的故障,如硬碟損壞了,那麼事務提交的資料可能就丟失了。這屬於『高可用性』的範疇。因此,事務只能保證資料庫的『高可靠性』,而『高可用性』需要整個系統共同配合實現。

事務的分類

1. 扁平事務

  • 它是實際生產環境中最常用、最簡單的事務型別。
  • 事務從BEGIN WORK開始,從COMMIT WORK或ROLLBACK WORK結束。
  • 缺點:發生錯誤時回滾到事務的起始位置,無法回滾部分操作。而回滾所有的操作開銷太大。

2. 帶有儲存點的扁平事務

這種事務能設定多個儲存點,當發生錯誤時可以回滾到事務中指定的儲存點,而不需要將整個事務回滾。

3. 鏈事務

4. 巢狀事務

5. 分散式事務

資料庫併發訪問會出現的問題

1. 更新丟失

當有兩個併發執行的事務,更新同一行資料,那麼有可能一個事務會把另一個事務的更新覆蓋掉。 
當資料庫沒有加任何鎖操作的情況下會發生。

2. 髒讀

一個事務讀到另一個尚未提交的事務中的資料。 
該資料可能會被回滾從而失效。 
如果第一個事務拿著失效的資料去處理那就發生錯誤了。

3. 不可重複讀

不可重複度的含義:一個事務對同一行資料讀了兩次,卻得到了不同的結果。它具體分為如下兩種情況: 
1. 虛讀:在事務1兩次讀取同一記錄的過程中,事務2對該記錄進行了修改,從而事務1第二次讀到了不一樣的記錄。 
2. 幻讀:事務1在兩次查詢的過程中,事務2對該表進行了插入、刪除操作,從而事務1第二次查詢的結果發生了變化。

與『髒讀』的區別? 
髒讀讀到的是尚未提交的資料,而不可重複讀讀到的是已經提交的資料,只不過在兩次讀的過程中資料被另一個事務改過了。

事務的隔離級別

資料庫事務的隔離級別有4個,由低到高依次為Read uncommitted 、Read committed 、Repeatable read 、Serializable ,這四個級別可以逐個解決髒讀 、不可重複讀 、幻讀 這幾類問題。 
title

1. Read uncommitted 讀未提交

在該級別下,一個事務對一行資料修改的過程中,不允許另一個事務對該行資料進行修改,但允許另一個事務對該行資料讀。 
因此本級別下,不會出現更新丟失,但會出現髒讀、不可重複讀。

2. Read committed 讀提交

在該級別下,未提交的寫事務不允許其他事務訪問該行,因此不會出現髒讀;但是讀取資料的事務允許其他事務的訪問該行資料,因此會出現不可重複讀的情況。

3. Repeatable read 重複讀

在該級別下,讀事務禁止寫事務,但允許讀事務,因此不會出現同一事務兩次讀到不同的資料的情況(不可重複讀),且寫事務禁止其他一切事務。

4. Serializable 序列化

該級別要求所有事務都必須序列執行,因此能避免一切因併發引起的問題,但效率很低。

隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。對於多數應用程式,可以優先考慮把資料庫系統的隔離級別設為Read Committed。它能夠避免髒讀取,而且具有較好的併發效能。儘管它會導致不可重複讀、幻讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,可以由應用程式採用悲觀鎖或樂觀鎖來控制。

使用事務的注意事項

1. 不要在迴圈中提交事務

2. 不要使用自動提交

3. 不要使用自動回滾

4. 不要使用長事務