平常的業務場景中,會出現多事務併發訪問數據庫的場景,首先咱們看一下在不考慮事務隔離級別,併發訪問數據庫的狀況下,可能出現的幾類問題。mysql
一、第一類丟失更新:A開啓A事務,B開啓B事務,數據count=100,B事務執行count+10=110,提交B事務。A事務回滾事務,count被從新回滾到100,B事務所作提交丟失。(A事 務撤回使B事務已做的提交失效)。這種問題現代關係型數據庫已經不會發生。程序員
二、第二類丟失更新:A開啓A事務,B開啓B事務,數據count=100,B事務執行count+10=110,提交B事務。A事務接着執行count-10=90,提交事務,count變爲90,B事務所作提交 丟失。(A事務提交覆蓋了B事務的提交)sql
三、髒讀:A開啓A事務,B開啓B事務,數據庫count=100,事務B執行count+10=110,可是未提交,事務A讀取count=110。事務B回滾,count從新變爲100,可是此時事務A一直以 爲count=110。(A事務讀取了B事務未提交,後面又回滾的更改)數據庫
四、不可重複讀:A開啓A事務,B開啓B事務,數據count=100,A事務第一次查詢count=100,B事務執行count+10=110,提交事務,A事務第二次查詢count=110。(A事務兩次讀取 同一數據不同)安全
五、幻讀:A開啓A事務、B開啓B事務,A事務根據where條件查詢出1條數據,B事務插入或刪除了符合同一where條件的1條數據,提交事務,A事務根據同一where條件第二次查詢 出2條或0條數據。(A事務兩次讀取的記錄條數不同)併發
咱們須要根據不一樣的場景屏蔽不一樣的問題,並非上述每種問題,咱們都須要避免,過多的控制會帶來性能上的丟失。因此數據庫提供了四種事務隔離機制。性能
一、讀未提交(read uncommited):顧名思義,即一個事務對數據進行更改後尚未提交,別的事務依然能夠讀取這個更改(原理:事務在讀取的時候沒有加任何鎖)。這種級別在實 際中不多用到,由於數據安全性過低,只能避免第一類丟失更新。事務
二、讀已提交(read commited):在一個事務修改數據的過程當中,若是沒有提交,其餘事務不能讀取這個改變(原理:更新時加行級排它鎖,直到事務結束,讀取時加行級共享鎖,一 旦讀完該行,當即釋放)。這種級別能夠避免髒讀。it
三、可重複讀(repeatable read):在一個事務讀取數據的過程當中,若是沒有提交,其餘事務不能更改這個數據(原理:更新時加行級排它鎖,直到事務結束,讀取時加行級共享鎖,直 到事務結束)。這種級別能夠避免髒讀和不可重複讀以及第二類丟失更新,也是mysql的默認隔離級別。table
四、序列化(serializable):能夠解決其餘級別都不能解決的幻讀(原理:讀取時加表級共享鎖,直到事務結束,更新時加表級排他鎖,直到事務結束)。
上述咱們提到了鎖,其實這也是數據庫實現數據安全的重要手段。從程序員的角度,鎖能夠分爲悲觀鎖和樂觀鎖;從數據庫系統的角度,鎖能夠分爲共享鎖、更新鎖和排它鎖;從鎖的粒度上,又能夠分爲行級鎖和表級鎖。關於鎖的部分,咱們見下一節。