併發操作與資料的不一致性
1,什麼是併發操作?
資料庫的一個重要特徵是:支援資料共享,也就是說允許多個使用者程式並行地存取資料庫中的資料;那麼,多使用者或多事物可能同時對同一資料進行操作,這成為併發操作。
2,併發操作可能帶來的影響?
如果不對併發操作進行控制的話,那麼就會存取不正確的資料,破壞資料的完整性。——為什麼這麼說?下面進行介紹
在此之前,先說一下事務的概念。
3,什麼是事務?
對一件完整的事兒,要麼做完整,要麼都不做。例如:學生選課—學生選上課時,需要將選課資訊寫入選課表的同時,更新課程表中的課程餘量;如果在新增選課資訊時,中斷了(不能進行餘量更新),那麼就會事務回滾,即,資料回滾到沒選課之前。
Begin Transaction
選課表中新增選課資訊;
更新課程表中的課程餘量;
Commit
RollBac
事務的SQL語句:
Begin Transaction開始事務
Commit提交事務
RollBack回滾
(注:事務中的多條SQL語句也是一條條執行的,當所有語句執行完後,提交事務,如果其中一條中斷,則事務回滾所有操作回到語句執行之前)
事務的併發主要是為了提高效率,但是,同時它也帶來了一定問題
4,併發操作帶來的問題?
之前講過併發操作——多使用者或多事務同時對同一資料進行操作;
因為事務中的語句也是一條條執行的,所以存在多使用者多事務同時對同一資料進行操作的情況;
併發操作帶來的問題:
(1)丟失修改
(2)髒讀
(3)不可重複讀
4.1丟失修改
當兩個或多個事務(或兩個或多個使用者)選擇同一行,然後基於最初選定的值更新該行時,會發生丟失更新問題。每個事務都不知道其它事務的存在(或每個使用者操作時並不會考慮同一時刻是否有別的使用者進行著同樣的操作)。最後的更新將重寫由其它事務所做的更新,這將導致資料丟失。
例子1:
事務T1,事務T2,資料庫中資料R=1000
- t1時刻,事務T1讀取R=1000;
- 過了一會兒 t2時刻,事務T2讀取R=1000;
- t3時刻,事務T1修改R=R-200(那麼R=800)寫入資料庫(此時,資料庫中R=800);
- 過了一會兒 t4時刻,事務T2修改R=R-100(因為在t2時刻讀到的資料為R=1000,那麼修改後R=900)寫入資料庫(此時,資料庫中R=900)
那麼最終,資料庫中R=900;資料對嗎?當然不對,因為T1、T2分別對R進行了-200 -100操作,最終資料應為R=700;事務T2的修改覆蓋了T1的修改——丟失修改問題
例子2:選課:學生A、學生B、課程1的餘量=20
- 學生A選擇課程1時,先讀出課程餘量20
- 然而同一時刻(也可是不同時刻,只要在學生A更新資料之前),學生B也讀出了課程1的餘量20,
- 學生A選擇此課程,課程1餘量-1,寫入資料庫,此時課程1的餘量=19;
- 學生B選擇此課程,課程1餘量-1(因為之前讀出的課程1餘量為20,-1後為19),寫入資料庫,此時課程1的餘量=19;
課程餘量=19資料正確嗎?不正確。實際情況課程餘量應更新為18;——B的修改覆蓋了A的修改—— 丟失修改問題。
解決辦法:加鎖,只允許併發一個更新事務。
4.2髒讀
當一個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,另外一個事務也訪問這個資料,然後使用了這個資料。因為這個資料是還沒有提交的資料,那麼另外一個事務讀到的這個資料是髒資料,依據髒資料所做的操作可能是不正確的。
髒資料就是已經修改的,存在於快取中,還未被寫入資料庫檔案中的資料,類似垃圾資料。比如會員已存不存在的,但資料庫中還存留著他的留言資訊,好友資訊等等,實際沒有作用,又佔地方,到時還要影響統計的正確性。
例子1:
事務T1,事務T2,資料庫中資料R=1000;
T1:
- Begin Transaction開始事務T1
- Read R=1000;//(1)
- R=R-200;//(2)此時R=800
- R=R+100;//(3)此時R=900
- Commit提交事務T1
- 當事務T1進行到第(2)後,即,資料庫中的資料R=800時;
- 事務T2開始讀R的值,讀出的值為R=800;但此時事務T1還沒有進行完整,還未提交事務;
- 之後事務T1進行第(3)步R=R+100,此時R=900事務T1提交,此時資料庫中R=900;
- 那麼在事務T1提交事務之前,事務T2讀出的資料(R=800)為髒資料;
例子2:
- 張三的工資為2000,元老闆把張三的工資改為了8000元(但未提交事務)
- 張三檢視自己的工資 ,發現工資變為了8000元
- 而後老闆發現改錯了,回滾了事務,張三的工資又變回了2000元
- 那麼,張三讀取的工資8000元就是髒資料。
解決辦法:如果在第一個事務提交前,任何其他事務不可讀取其修改過的值,則可以避免該問題。
4.3不可重複讀
當第二個事務多次訪問同一行而且每次讀取不同的資料時,會發生不一致的分析問題。不一致的分析與未確認的相關性類似,因為其它事務也是正在更改第二個事務正在讀取的資料。然而,在不一致的分析中,第二個事務讀取的資料是由已進行了更改的事務提交的。而且,不一致的分析涉及多次(兩次或更多)讀取同一行,而且每次資訊都由其它事務更改;因而該行被非重複讀取。
在一個事務中前後兩次讀取的結果並不致,導致了不可重複讀。
例子1:事務T1、事務T2、張三的工資=1000
- 事務T1中,張三讀取了自己的工資為1000元,操作並沒有完成
- 此時(事務T1讀取了張三工資為1000元)事務2中,修改了張三的工資為2000元,並提交了事務.
- 此時(事務T1讀取了張三工資為1000元,事務T2修改了張三的工資為2000元)在事務1中,張三再次讀取自己的工資時,工資變為了2000
那麼,同一個事務中,前後讀取的資料不一致—— 不可重複讀問題。
解決辦法:如果只有在修改事務完全提交之後才可以讀取資料,則可以避免該問題。
總結:
- 事務的併發主要是為了提高效率,但是,同時它也帶來了一定問題——丟失修改、讀髒資料、不可重複讀
- 結合生活中例項,理解丟失修改、讀髒資料、不可重複讀問題。
--------------------- 作者:hanxuemin12345 來源:CSDN 原文:https://blog.csdn.net/hanxuemin12345/article/details/21740699