數據庫事務並發了解一下唄
看了兩天Java源碼,有點懵、今天翻了一波面試的交流貼,唉,看看各大公司出的那些生怕你通過的面試題、真是覺得自己前途一片昏暗,片昏暗,昏暗,暗。。。
but,習還是要學的,從面試題裏看到有問數據庫並發問題的,之前上課明明學過數據庫原理的,但是看著題目大腦還是一片空白,片空白,空白,白。。。都是之間學習不總結的坑
so,來吧,再學一遍,同時梳理總結一下。好記性不如爛筆頭頭頭頭頭!
數據庫事務的四大特性(ACID)
原子性(Atomicity):是指一個事務中包含的所有操作,要麽全做,要麽全不做。
一致性(Consistency):指數據庫從一個一致性狀態轉移到另一個一致性狀態,只包含已提交的事務,如果某些事務尚未完成被迫中斷,而該事務對數據庫的修改已經寫入物理數據庫,此時數據庫處於一個不正確的狀態。
隔離性(Isolation):是指各個並發事務之間互不幹擾。
持久性(Durability):是指事務一旦提交,對數據庫的修改是持久的,即使 數據庫發生故障也能進行恢復。
數據庫事務並發引起的問題
臟讀:也叫讀臟數據,是指當前事務讀取了其他事務還未提交的修改。發生臟讀是由於一個事務在提交之前對數據庫的修改對其他事務是可見的。舉個小栗子:例如A和B在同時賣票,目前系統僅剩一張票,此時尼古拉斯去A處買了一張票,A將數據庫中的余票量-1,此時有人去B處買了一張票,B查詢數據庫發現現在木有票了,於是告訴買者沒票了。但是!B處買者走了以後,尼古拉斯突然不想買了,於是A取消之前的操作,並提交事務,此時就導致兩處都沒有賣出票。這就是因為B讀取了A沒有提交的數據。
不可重復讀:是指一個事務兩次讀取的結果不一樣,這是由於在兩次讀取的間隔另一個事務修改了數據庫並提交。不可重復讀和讀臟數據的區別是臟讀發生在事務提交前,不可重復讀是發生在事務提交後。
幻讀:事務在操作過程中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據或者缺少了第一次查詢中出現的數據(這裏並不要求兩次查詢的SQL語句相同)。這是因為在兩次查詢過程中有另外一個事務插入數據造成的。不可重復讀和幻讀的區別在於前者是針對某一條記錄,後者是針對一批記錄。
以上是一些讀問題,還有一些更新問題
更新丟失問題
第一類更新丟失問題:A和B對數據庫進行更新,A失敗回滾到原點把B對數據庫的更新給覆蓋掉了。
第二類更新丟失問題:A和B對數據庫進行更新,A對數據庫的更新覆蓋了B對數據庫的更新。
對於事務並發引起的問題及一些例子可以參考https://blog.csdn.net/starlh35/article/details/76445267
事務的四種隔離級別
為了保證事務的隔離性,數據庫提供了四種隔離級別
讀未提交:一個事務在進行寫操作時,不允許其他事務進行寫操作,但允許其他數據的讀操作。這個級別的隔離可以避免更新丟失,但是會導致讀臟數據
讀已提交:未提交的寫事務將會禁止其他事務訪問該行。一個這個級別的隔離可以解決讀臟數據的問題,但仍然存在不可重復讀的問題
可重復讀:讀取數據的事務禁止其他事務的寫操作(避免不可重復讀),但允許讀事務,寫事務則禁止其他一切事務(避免臟讀)。該級別仍存在幻讀的問題
串行化 :要求事務序列化也就是只能一個接一個執行,該級別的隔離可以避免臟讀,不可重復讀以及幻讀的問題,但是性能不佳,一般很少使用
測試數據庫的隔離級別參考https://www.jianshu.com/p/8d735db9c2c0 和 https://www.jb51.net/article/116477.htm一定要看,便於理解。
在mysql中查看當前事務的隔離級別:
select @@tx_isolation;
在MySQL數據庫中設置事務的隔離 級別:
set [glogal | session] transaction isolation level 隔離級別名稱;
或者
set tx_isolation=’隔離級別名稱;’
好了,先醬吧、
數據庫事務並發了解一下唄