最近做的《選修課系統》需要考慮這樣乙個問題:資料庫的併發操作帶來的資料庫資料不一致問題——因為是全校性選修課,同一時間點大批學生選課,那麼必然存在多名學生同時對同一資料進行操作
是的問題,如果這種併發操作不加以控制的話,必會造成資料的不一致。
一直知道有這種問題,並且知道這種問題的解決方法——加鎖;但是有些東西之前了解的並不是很透徹,於是好好研究了一天,覺得理解的還可以,先總結一部分。
資料庫的乙個重要特徵是:支援資料共享,也就是說允許多個使用者程式並行地訪問資料庫中的資料;那麼,多使用者或多事物可能同時對同一資料進行操作,這成為併發操作。
如果不對併發操作進行控制的話,那麼就會訪問不正確的資料,破壞資料的完整性。——為什麼這麼說?下面進行介紹
在此之前,先說一下事務的概念。
對一件完整的事兒,要麼做完整,要麼都不做。例如:學生選課—學生選上課時,需要將選課資訊寫入選課表的同時,更新課程表中的課程餘量;如果在新增選課資訊時,中斷了(不能進行餘量更新),那麼就會事務回滾,即,資料回滾到沒選課之前。
begin transaction
選課表中新增選課資訊;
更新課程表中的課程餘量;
commit
rollbac
事務的sql
語句:
begin
transaction
開始事務
commit
提交事務
rollback回滾
(注:事務中的多條
sql語句也是一條條執行的
,當所有語句執行完後,提交事務,如果其中一條中斷,則事務回滾
所有操作回到語句執行之前)
事務的併發主要是為了提高效率,但是,同時它也帶來了一定問題
之前講過併發操作——多使用者或多事務同時對同一資料進行操作;
因為事務中的語句也是一條條執行的,所以存在多使用者多事務同時對同一資料進行操作的情況;
併發操作帶來的問題:(1
)丟失修改 (
2)髒讀 (
3)不可重複讀
當兩個或多個事務(或兩個或多個使用者)選擇同一行,然後基於最初選定的值更新該行時,會發生丟失更新問題。每個事務都不知道其它事務的存在(或每個使用者操作時並不會考慮同一時刻是否有別的使用者進行著同樣的操作)。最後的更新將重寫由其它事務所做的更新,這將導致資料丟失。 例子
1:事務t1
,事務t2
,資料庫中資料
r=1000
a.t1
時刻,事務
t1讀取
r=1000;
b.過了一會兒
t2時刻,事務
t2讀取
r=1000;
c.t3
時刻,事務
t1修改
r=r-200(
那麼r=800)
寫入資料庫
(此時,資料庫中
r=800);
d.過了一會兒
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.學生
a選擇課程
1時,先讀出課程餘量20
b.然而
同一時刻(也可是不同時刻,只要在學生a更新資料之前),學生
b也讀出了課程
1的餘量20,
c.學生
a選擇此課程,課程1餘量
-1,寫入資料庫,此時課程
1的餘量
=19; d.
學生b選擇此課程,課程1餘量
-1(因為之前讀出的課程
1餘量為20,
-1後為
19),寫入資料庫,此時課程
1的餘量
=19;
課程餘量
=19資料正確嗎?不正確。實際情況課程餘量應更新為
18;——
b的修改覆蓋了
a的修改
——丟失修改問題。
解決辦法:加鎖,只允許併發乙個更新事務。
當乙個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,
另外乙個事務也訪問這個資料,然後使用了這個資料。因為這個資料是還沒有提交的資料,那麼另外乙個
事務讀到的這個資料是髒資料,依據髒資料所做的操作可能是不正確的。例子1
:事務t
1,事務
t2,資料庫中資料
r=1000;
t1:
begin
transaction
開始事務t1
readr=1000;(1)
r=r-200;(2)
此時r=800
r=r+100;(3)
此時r=900
commit
提交事務t1
a.當事務
t1進行到第
(2)後,即,資料庫中的資料
r=800時;
b.事務t2
開始讀r
的值,讀出的值為
r=800
;但此時事務
t1還沒有進行完整,還未提交事務;
c.之後事務
t1進行第
(3)步
r=r+100
,此時r=900
事務t1
提交,此時資料庫中
r=900;
那麼在事務
t1提交事務之前,事務
t2讀出的資料
(r=800)
為臟資料; 例子
2: a
.張三的工資為
2000,
元老闆把張三
的工資改為了
8000元(
但未提交事務
) 2.
張三檢視
自己的工資
,發現工資變為了
8000元
3.而後老闆發現改錯了,回滾了事務,張三
的工資又變
回了2000元
那麼,張三讀取的工資
8000
元就是髒資料。
解決辦法:如果在第乙個事務提交前,任何其他事務不可讀取其修改過的值,則可
以避免該問題。
當第二個事務多次訪問同一行而且每次讀取不同的資料時,會發生不一致的分析問題。不一致的分析與未確認的相關性類似,因為其它事務也是正在更改第二個事務正在讀取的資料。然而,在不一致的分析中,第二個事務讀取的資料是由已進行了更改的事務提交的。而且,不一致的分析涉及多次(兩次或更多)讀取同一行,而且每次資訊都由其它事務更改;因而該行被非重複讀取。
在乙個事務中前後兩次讀取的結果並不致,導致了不可重複讀。例子1
:事務t
1、事務
t2、張三的工資
=1000 a
.事務t1中
,張三讀取了
自己的工資為
1000元,
操作並沒有完成 b
.此時(事務
t1讀取了張三工資為
1000元)
事務2中,修改了
張三的工資為
2000元,
並提交了事務.
c.此時(事務t1
讀取了張三工資為
1000
元,事務
t2修改了張三的工資為
2000
元)在事務1中,
張三再次讀取自己的工資時,工資變為了
2000
那麼,同乙個事務中,前後讀取的資料不一致
——不可重複讀問題。
解決辦法:如果只有在修改事務完全提交之後才可以讀取資料,則可以避免該問題。(1
)事務的併發主要是為了提高效率,但是,同時它也帶來了一定問題——丟失修改、讀髒資料、不可重複讀 (
2)結合生活中例項,理解丟失修改、讀髒資料、不可重複讀問題。
個人理解,如果**有理解偏差,忘糾正!
下篇部落格會總結「鎖」的概念,並解釋「鎖」是如何解決併發造成的資料不一致問題。
併發操作與資料的不一致性
最近做的 選修課系統 需要考慮這樣乙個問題 資料庫的併發操作帶來的資料庫資料不一致問題 因為是全校性選修課,同一時間點大批學生選課,那麼必然存在多名學生同時對同一資料進行操作 是的問題,如果這種併發操作不加以控制的話,必會造成資料的不一致。一直知道有這種問題,並且知道這種問題的解決方法 加鎖 但是有...
併發操作與資料的不一致性
最近做的 選修課系統 需要考慮這樣乙個問題 資料庫的併發操作帶來的資料庫資料不一致問題 因為是全校性選修課,同一時間點大批學生選課,那麼必然存在多名學生同時對同一資料進行操作 是的問題,如果這種併發操作不加以控制的話,必會造成資料的不一致。一直知道有這種問題,並且知道這種問題的解決方法 加鎖 但是有...
併發操作會帶來資料的不一致性
髒讀 就是指當乙個事務對資料進行了修改但還沒有提交到資料庫時,另乙個事務訪問並使用了這個資料。不可重複讀 在乙個事務內兩次讀資料之間,第二個事務訪問該資料並進行了修改。丟失修改 兩個事務讀入同一資料並修改,t2提交的結果破壞了t1提交的結果。例如t1讀a修改為a 1,t2也讀a修改為a 1 實際上應...