《數(shù)據(jù)隔離級別》由會員分享,可在線閱讀,更多相關(guān)《數(shù)據(jù)隔離級別(19頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、單擊此處編輯母版標題樣式,,單擊此處編輯母版文本樣式,,第二級,,第三級,,第四級,,第五級,,,*,數(shù)據(jù)隔離級別,,,,,隔離級別定義了事務與事務之間的隔離程度。,,隔離級別與并發(fā)性是互為矛盾的:隔離程度越高,數(shù)據(jù)庫的并發(fā)性越差;隔離程度越低,數(shù)據(jù)庫的并發(fā)性越好。,,,ANSI/ISO SQL92,標準定義了一些數(shù)據(jù)庫操作的隔離級別:,,未提交讀(,read uncommitted,),,提交讀(,read committed,),,重復讀(,repeatable read,),,序列化(,serializable,),,,通過一些現(xiàn)象,可以反映出隔離級別的效果。這些現(xiàn)象有:,,,更新丟失(
2、,lost update,):當系統(tǒng)允許兩個事務同時更新同一數(shù)據(jù)是,發(fā)生更新丟失。,,,臟讀(,dirty read,):當一個事務讀取另一個事務尚未提交的修改時,產(chǎn)生臟讀。,,,非重復讀(,nonrepeatable,read,):同一查詢在同一事務中多次進行,由于其他提交事務所做的修改,每次返回不同的結(jié)果集,此時發(fā)生非重復讀。,,,幻像(,phantom read,):同一查詢在同一事務中多次進行,由于其他提交事務所做的插入或刪除操作,每次返回不同的結(jié)果集,此時發(fā)生幻像讀。,,,下面是隔離級別及其對應的可能出現(xiàn)或不可能出現(xiàn)的現(xiàn)象,,,臟讀,: Mary,的原工資為,1000,,財務人員將
3、,Mary,的工資改為了,8000,,但未提交事務,,,Connection con1 =,getConnection,();,con.setAutoCommit(,false,);,,update employee set salary = 8000 where,empId,="Mary";,,,,與此同時,,Mary,正在讀取自己的工資,,,Connection con2 =,getConnection,();,,select salary,fromemployee,where,empId,="Mary"; mit();,,,Mary,發(fā)現(xiàn)自己的工資變?yōu)榱?8000,,歡天喜地! 而財務
4、發(fā)現(xiàn)操作有誤,而回滾了事務,,Mary,的工資又變?yōu)榱?1000 //con1 con1.rollback();,像這樣,,Mary,記取的工資數(shù),8000,是一個臟數(shù)據(jù)。,READ_COMMITTED,保證一個事務修改的數(shù)據(jù)提交后才能被另外一個事務讀取。另外一個事務不能讀取該事務未提交的數(shù)據(jù)。這種事務隔離級別可以避免臟讀出現(xiàn),但是可能會出現(xiàn)不可重復讀和幻像讀。,,,,不可重復讀:,,,在事務,1,中,,Mary,讀取了自己的工資為,1000,,操作并沒有完成,con1 =,getConnection,();,,select salary from employee,empId,="Mary
5、";,在事務,2,中,這時財務人員修改了,Mary,的工資為,2000,,并提交了事務,. con2 =,getConnection,();,,update employee set salary = 2000;,在事務,1,中,,Mary,再次讀取自己的工資時,工資變?yōu)榱?2000 //con1 select salary from employee,empId,="Mary";,,,在一個事務中前后兩次讀取的結(jié)果并不致,導致了不可重復讀。 使用,REPEATABLE_READ,可以避免這種情況發(fā)生。,,,,幻像讀:,,目前工資為,1000,的員工有,10,人。 事務,1,,讀取所
6、有工資為,1000,的員工。,,con1 =,getConnection,();,,Select * from employee where salary =1000;,共讀取,10,條記錄 這時另一個事務向,employee,表插入了一條員工記錄,工資也為,1000 con2 =,getConnection,();,,Insert into,employee(empId,salary,) values("Lili",1000); mit();,事務,1,再次讀取所有工資為,1000,的員工,//con1 select * from employee where salary =1000
7、;,,,共讀取到了,11,條記錄,這就產(chǎn)生了幻像讀。,,,ISOLATION_SERIALIZABLE,能避免這樣的情況發(fā)生。但是這樣也耗費了最大的資源。,,,,大多數(shù)數(shù)據(jù)庫的默認隔離級別為,:?Read,Commited,,,如,Sql,Server?,?Oracle.,,,,少數(shù)數(shù)據(jù)庫默認的隔離級別為,Repeatable?Read,,如,MySQL,,InnoDB,存儲引擎,,鎖的概念,2-1,,鎖是數(shù)據(jù)庫用來控制共享資源并發(fā)訪問的機制。,,鎖用于保護正在被修改的數(shù)據(jù),,直到提交或回滾了事務之后,其他用戶才可以更新數(shù)據(jù),,,鎖的概念,2-2,,修改表,修改表,拒絕訪問,Toy_ID,Na
8、me,Price,T001,Barbie,20,T002,GI Joe,45,,鎖定的優(yōu)點,,一致性,,-,一次只允許一個用戶修改數(shù)據(jù),,完整性,,-,為所有用戶提供正確的數(shù)據(jù)。如果一個用戶進行了修改并保存,所做的修改將反映給所有用戶,并行性,-允許多個用戶訪問同一數(shù)據(jù),Toy_ID,Name,Price,T001,Barbie,20,T002,GI Joe,45,修改表中,,的數(shù)據(jù),查看表中的數(shù)據(jù),允許訪問,,表級鎖,行級鎖,鎖的類型,,鎖的類型,,行級鎖,3-1,,Toy_ID,Name,Price,T001,Barbie,20,T002,GI Joe,45,更新,T00,2,行,更新,T
9、001,,行,行被鎖定,對正在被修改的行進行鎖定。其他用戶可以訪問除被鎖定的行以外的行,允許訪問,,行級鎖,3-2,,行級鎖是一種排他鎖,防止其他事務修改此行,,在使用以下語句時,,Oracle,會自動應用行級鎖:,,INSERT,,UPDATE,,DELETE,,SELECT … FOR UPDATE,,SELECT … FOR UPDATE,語句允許用戶一次鎖定多條記錄進行更新,,使用,COMMIT,或,ROLLBACK,語句釋放鎖,,行級鎖,3-3,,SELECT … FOR UPDATE,語法,:,,,SELECT … FOR UPDATE [OF columns][WAIT n |
10、 NOWAIT];,SQL> SELECT * FROM,order_master,WHERE,vencode,=’V002’,,FOR UPDATE OF,odate,,,del_date,;,,SQL> UPDATE,order_master,SET,del_date,=’28-8,月,-05’,,WHERE,vencode,=’V002’;,,SQL> COMMIT;,SQL> SELECT * FROM,order_master,WHERE,vencode,=’V002’,,FOR UPDATE WAIT 5;,SQL> SELECT * FROM,order_master,WHERE
11、,vencode,=’V002’,,FOR UPDATE NOWAIT;,,表級鎖,3-1,,Toy_ID,Name,Price,T001,Barbie,20,T002,GI Joe,45,修改表中的行,更新表,拒絕訪問,鎖定整個表,限制其他用戶對表的訪問。,,表級鎖,3-2,,表級鎖類型,行共享,行排他,共享,使用命令顯示地鎖定表,應用表級鎖的語法是,:,,,LOCK TABLE,table_name,IN mode,MODE,;,共享行排他,排他,,表級鎖,3-3,,行共享,(ROW SHARE) –,禁止排他鎖定表,,行排他,(ROW EXCLUSIVE) –,禁止使用排他鎖和共享鎖,,
12、共享鎖,(SHARE),,鎖定表,僅允許其他用戶查詢表中的行,,禁止其他用戶插入、更新和刪除行,,多個用戶可以同時在同一個表上應用此鎖,,共享行排他,(SHARE ROW EXCLUSIVE) –,比共享鎖更多的限制,禁止使用共享鎖及更高的鎖,,排他,(EXCLUSIVE) –,限制最強的表鎖,僅允許其他用戶查詢該表的行。禁止修改和鎖定表,,死鎖,,當兩個事務相互等待對方釋放資源時,就會形成死鎖,,Oracle,會自動檢測死鎖,并通過結(jié)束其中的一個事務來解決死鎖,,右邊是一個死鎖的例子,T,1,T,2,lock,(D,1,),時間,lock,(D,2,),lock,(D,2,),lock,(D,1,),等待,等待,…,…,,