目錄
- 資料庫事務的四大特性
- ⑴ 原子性(Atomicity)
- ⑵ 一致性(Consistency)
- ⑶ 隔離性(Isolation)
- ⑷ 持久性(Durability)
- SQL的4種隔離級別
- Read Uncommitted(讀取未提交內容)
- Read Committed(讀取提交內容)
- Repeatable Read(可重讀)
- Serializable(可串行化)
- 設定MySQL的事務隔離級別
- windows:
- Linux
資料庫事務的四大特性
本篇講訴資料庫中事務的四大特性(ACID),并且將會詳細地說明事務的隔離級別,
如果一個資料庫聲稱支持事務的操作,那么該資料庫必須要具備以下四個特性:
⑴ 原子性(Atomicity)
原子性是指事務包含的所有操作要么全部成功,要么全部失敗回滾,這和前面兩篇博客介紹事務的功能是一樣的概念,因此事務的操作如果成功就必須要完全應用到資料庫,如果操作失敗則不能對資料庫有任何影響,
⑵ 一致性(Consistency)
一致性是指事務必須使資料庫從一個一致性狀態變換到另一個一致性狀態,也就是說一個事務執行之前和執行之后都必須處于一致性狀態,
拿轉賬來說,假設用戶A和用戶B兩者的錢加起來一共是5000,那么不管A和B之間如何轉賬,轉幾次賬,事務結束后兩個用戶的錢相加起來應該還得是5000,這就是事務的一致性,
⑶ 隔離性(Isolation)
隔離性是當多個用戶并發訪問資料庫時,比如操作同一張表時,資料庫為每一個用戶開啟的事務,不能被其他事務的操作所干擾,多個并發事務之間要相互隔離,
即要達到這么一種效果:對于任意兩個并發的事務T1和T2,在事務T1看來,T2要么在T1開始之前就已經結束,要么在T1結束之后才開始,這樣每個事務都感覺不到有其他事務在并發地執行,
關于事務的隔離性資料庫提供了多種隔離級別,稍后會介紹到,
⑷ 持久性(Durability)
持久性是指一個事務一旦被提交了,那么對資料庫中的資料的改變就是永久性的,即便是在資料庫系統遇到故障的情況下也不會丟失提交事務的操作,
例如我們在使用JDBC操作資料庫時,在提交事務方法后,提示用戶事務操作完成,當我們程式執行完成直到看到提示后,就可以認定事務以及正確提交,即使這時候資料庫出現了問題,也必須要將我們的事務完全執行完成,否則就會造成我們看到提示事務處理完畢,但是資料庫因為故障而沒有執行事務的重大錯誤,
以上介紹完事務的四大特性(簡稱ACID),現在重點來說明下事務的隔離性,當多個執行緒都開啟事務操作資料庫中的資料時,資料庫系統要能進行隔離操作,以保證各個執行緒獲取資料的準確性,在介紹資料庫提供的各種隔離級別之前,我們先看看如果不考慮事務的隔離性,會發生的幾種問題:
SQL的4種隔離級別
Read Uncommitted(讀取未提交內容)
? 在該隔離級別,所有事務都可以看到其他未提交事務的執行結果,本隔離級別很少用于實際應用,因為它的性能也不比其他級別好多少,讀取未提交的資料,也被稱之為臟讀(Dirty Read),
Read Committed(讀取提交內容)
這是大多數資料庫系統的默認隔離級別(但不是MySQL默認的),它滿足了隔離的簡單定義:一個事務只能看見已經提交事務所做的改變,這種隔離級別 也支持所謂的不可重復讀(Nonrepeatable Read),因為同一事務的其他實體在該實體處理其間可能會有新的commit,所以同一select可能回傳不同結果,
Repeatable Read(可重讀)
(Mysql默認為此項:REPEATABLE-READ)
? 這是MySQL的默認事務隔離級別,它確保同一事務的多個實體在并發讀取資料時,會看到同樣的資料行,不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read),簡單的說,幻讀指當用戶讀取某一范圍的資料行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的資料行時,會發現有新的“幻影” 行,InnoDB和Falcon存盤引擎通過多版本并發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題,
Serializable(可串行化)
? 這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題,簡言之,它是在每個讀的資料行上加上共享鎖,在這個級別,可能導致大量的超時現象和鎖競爭,
?
讀取的是同一個資料時, 容易發生的問題有:
臟讀(Drity Read):某個事務已更新一份資料,另一個事務在此時讀取了同一份資料,由于某些原因,前一個RollBack了操作,則后一個事務所讀取的資料就會是不正確的,
不可重復讀(Non-repeatable read):在一個事務的兩次查詢之中資料不一致,這可能是兩次查詢程序中間插入了一個事務更新的原有的資料,
幻讀(Phantom Read):在一個事務的兩次查詢中資料筆數不一致,例如有一個事務查詢了幾列(Row)資料,而另一個事務卻在此時插入了新的幾列資料,先前的事務在接下來的查詢中,就會發現有幾列資料是它先前所沒有的,
| 隔離級別 | 臟讀 | 不可重復度 | 幻讀 |
|---|---|---|---|
| Read Uncommitted(讀取未提交內容) | √ | √ | √ |
| Read Committed(讀取提交內容) | × | √ | √ |
| Repeatable Read(可重讀) | × | × | √ |
| Serializable(可串行化) | × | × | × |
設定MySQL的事務隔離級別
windows:
查詢顯示當前的隔離級別
mysql> show global variables like '%isolation%';
+-----------------------+-----------------+
| Variable_name | Value |
+-----------------------+-----------------+
| transaction_isolation | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)
設定隔離級別
mysql> set global transaction_isolation ='read-committed';
Query OK, 0 rows affected (0.00 sec)
mysql> show global variables like '%isolation%';
+-----------------------+----------------+
| Variable_name | Value |
+-----------------------+----------------+
| transaction_isolation | READ-COMMITTED |
+-----------------------+----------------+
1 row in set (0.00 sec)
查看隔離級別也可以(前提是知道具體變數名):
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
1 row in set (0.00 sec)
Linux
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
在位置:
lc-messages-dir = /usr/share/mysql
skip-external-locking
后面添加(讀取提交內容):
transaction-isolation = READ-COMMITTED
保存后重啟mysql服務:
sudo service mysql restart
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/19730.html
標籤:MySQL
