事務的隔離性是指多個事務併發執行的時候相互之間不受到彼此的干擾的特性,隔離性是事務acid特性中的i,根據隔離程度從低到高分為read uncommitted(讀未提交),read committed(讀已提交),repeatable read(可重複讀),serializable(序列化)四種隔離級別。在具體介紹事務隔離性前先介紹幾個名詞,以便說明資料庫在併發操作時候可能存在的問題,以便展開來**這四種隔離級別對應存在哪些問題,哪些隔離級別解決了哪些問題。
如上圖開啟兩個會話來模擬兩個執行緒同時去訪問資料庫表table中id=1的記錄,假設兩個會話開啟前資料庫中table表中id=1的記錄行裡面的列age值為5。會話1和2一開始都開啟了顯示的事務(只有執行commit命令才會提交資料的修改),會話2首先更新了table中id=1的記錄行的age列的值為10(更新前值為5),在會話2執行commit提交前,會話1通過select語句查詢id=1的記錄行中age列的值,這時候如果存在髒讀,則會話1讀取到的age的值是10而不是5了,雖然會話2的更新還沒有提交。那麼髒讀存在什麼問題那?如果會話2最後提交了,那麼會話1雖然在會話2還沒提交就讀取到了修改的值,但是也沒什麼影響;但是如果會話1讀取到會話2沒有提交的資料後,會話2執行了rollback,也就是沒有把修改重新整理到資料庫,但是會話1已經使用了修改的資料,這就出現了錯誤。
如上圖假設資料庫表table裡面id=1的記錄行中age列一開始值為5,然後會話1和會話2分別開啟了乙個事務,會話1首先查詢id=1的記錄中age字段值為5,然後會話2修改id=1的記錄中age的值為10然後提交了事務,然後會話1再次搜出id=1的記錄中age的值,如果出現了不可重複讀,則這時候搜出來的age的值為10而不是5。需要注意的是會話1兩次查詢是在同乙個事務內進行的,期間事務並沒有提交。不可重複讀的存在顯得不是那麼不可容忍,畢竟讀取的是已經提交了的資料。
如上圖假設表table裡面一開始有乙個id=3的記錄,會話1首先開啟了乙個事務,然後查詢id>2的記錄,會發現結果只有乙個記錄,然後會話2開啟事務插入了id=5的乙個記錄,然後提交。這時候會話1再次查詢id>2的記錄,如果存在幻讀,則這時候會話1會看到兩條記錄。
注:髒讀是指乙個事務讀取到了其他事務沒有提交的資料,不可重複讀是指乙個事務內多次根據同乙個查詢條件查詢出來的同一行記錄的值不一樣,幻讀是指乙個事務內多次根據同個條件查出來的記錄行數不一樣。為了解決事務併發帶來的問題,才有了事務規範中的四個事務隔離級別,不同隔離級別對上面問題部分或者全部做了避免。
更多spring事務傳播性與事務隔離性的諮詢可以單擊我
更多關於分布式系統中服務降級策略的知識可以單擊 單擊我
想系統學dubbo的單擊我
想學併發的童鞋可以 單擊我
髒讀,不可重複讀,幻讀
髒讀,不可重複讀,幻讀是由於資料庫事務的隔離性導致的問題。髒讀 乙個事務讀取到了其它未提交事務操作的記錄。不可重複讀 乙個事務a內,首次查詢到一條相同記錄,然後事務b修改該條記錄並提交,事務a再次執行相同查詢,得到了事務b更新後的結果,事務a兩次相同的查詢,卻得到了不同的結果,這個叫做不可重複讀。是...
髒讀 不可重複讀 幻讀
髒讀 事務a使用了資料,但是還沒來得及提交,事務b就使用了這個資料,對於事務b來說就是髒讀。允許髒讀 sql server select from category with nolock 不可重複讀 事務a在9點和12點都會操作乙份資料,但是在10點的時候,事務b也操作了該份資料,並且使其數值進行...
髒讀 不可重複讀 幻讀
總結 對於不可重複讀和幻讀的區別是 不可重複讀圈了一塊地,這塊地不允許任何人動用,但是不管旁邊的地方是否開闢了一塊地。幻讀是不僅是圈的地,而且附近也不允許有新的地。這個對於區間查詢會有影響。所以不可重複讀和幻讀最大的區別是區間查詢的結果會不會一樣。幻讀保證結果一樣,但是不可重複讀不保證。mysql的...