【資料庫】sql server 2012資料庫基礎-併發控制-實驗報告
這是大三第一學期《資料庫基礎》的實驗報告,總共15個實驗,前12個百度文庫都有,後面三個網上找不到都是我自己花了很多時間琢磨出來的,希望對大家,以及將來的我有所幫助!
實驗13使用者管理及許可權管理 點我檢視
實驗14併發控制 本文
實驗15資料恢復 點我檢視
課程名稱 資料庫基礎
實驗專案 實驗14 併發控制
1.實驗目的:
理解和體會事務、封鎖、死鎖和併發控制等內容,加強對DBMS功能的認識。
2.實驗內容:
事務、封鎖、死鎖和併發控制
3.實驗要求:
- 獨立完成本實驗,以多個使用者身份登入,建立管理多個事務。
- 設計一組操作產生“髒”讀問題,然後通過封鎖避免“髒”讀問題。
- 設計一組操作產生不可重複讀問題,然後通過封鎖避免不可重複讀問題。
- 設計一組操作產生丟失更新問題,然後通過封鎖避免丟失更新問題。
- 設計一組產生死鎖的操作,再利用相同順序法有效的避免死鎖。
- 在實驗報告中要給出具體的操作步驟和過程,並針對各種情況做出具體的分析和討論,很好的體會事務的性質和併發控制的作用。
4.實驗準備
(1) 查詢一個已經被其他事務更新、但尚未提交的元組,將會引起“髒”讀問題;為避免該問題應該實施共享封鎖。
(2) 為避免不可重複讀問題,應該將共享封鎖保持到事務結束。
(3) 為避免丟失更新問題,應該實施獨佔封鎖或更新封鎖。
(4) SQL Server的封鎖操作是在相關語句的“WITH(<TABLE_HINT>)”子句中完成的。
(5) 設定隔離級別的命令是:
SET TRANSACTION ISOLATION LEVEL
{READ COMMITTED
|READ UNCOMMITTED
|REPEATABLE READ
|SERIALIZABLE}
5.實驗過程(含程式碼、實驗過程、遇到的問題和解決方法等):
第一題:設計一組操作產生“髒”讀問題,然後通過封鎖避免“髒”讀問題。
1.1概念:我個人覺得髒讀就是A事務讀到了B事務未提交的資料。(A事務修改資料1後,B事務讀取了當前的資料1,然後A因為某種錯誤回檔,導致B事務讀取的資料錯誤)。通俗來說就是A事務放了B事務的鴿子。
1.2整體思路:
先執行一個事務A ( 1.修改課程學時資料為8 ; 2.等待20秒 ; 3.回滾資料,學時還原為6 ),在事務A的第二步等待的時候,執行事務B ( 1.查詢學時; 2. 等待20秒; 3. 查詢學時)。其中事務B第一次查詢是事務A中間的等待期,所以學時為8,第二次查詢在事務A結束後,所以學時為6.
1.3 程式碼截圖:
首先我們在第一個查詢頁面執行以下程式碼:
圖 1 查詢視窗1 先更新學時為‘8 ’ 後回滾
程式碼解析:
以上第一行程式碼為:事務zwz1的開始標誌
第二行程式碼:更新課程表中課程編號為1128的學時為8
第三行程式碼:等待20秒延遲
第四行程式碼:回滾第二行程式碼,恢復到該事務未執行的狀態
第五行程式碼:查詢課程表中課程編號為1128的所有資訊
接下來在查詢視窗2,執行以下程式碼:
圖 2 查詢視窗2 分別在事務A 等待期 和 結束後 查詢學時
程式碼解析:
以上第一行程式碼為:在無鎖的情況下查詢課程表中課程編號為1128的所有資訊(為錯誤資訊)
第二行程式碼:等待20秒的時間
第三行程式碼:再次查詢,發現數據不一致(本次為正確資訊)
接下來是加封鎖的情況:
圖 3 加了寫讀鎖後(不加也一樣),視窗1回滾後 學時還是6 不變
注:和前面不加封鎖對比,多了第一行程式碼,即加上一個“寫讀鎖”,個人理解為“當事務A想讀取某資料,必須要等當前其他事務修改完,才能讀”
圖 4 加了寫讀鎖之後 事務B等事務A全部執行完畢後再執行 所以結果都是6
注:視窗二和前面不加封鎖相比,也是多了第一行程式碼,執行的時候能明顯感覺到運行了40秒,即等視窗1執行完畢後再執行視窗2的事務。
第二題:設計一組操作產生不可重複讀問題,然後通過封鎖避免不可重複讀問題。
2.1 概念:事務A讀某資料後,事務B將其修改,然後事務A再次讀資料和之前的不一樣。通俗理解為被調包。
2.2 總體思路:事務A讀取1128號課程資料後,等待5秒,然後事務A再次讀取該課程資料。其中事務B利用事務A的等待期,對該課程資料進行修改。
2.3程式碼截圖:
圖 5 事務A三部曲:讀取資料 ;等待期 ; 讀取資料 。發現數據不一致
圖 6 事務B 在事務A等待期內 對資料進行修改
解決方案:設定隔離級別 :repeatable read(可重複讀) 書本179頁
思路:在原有基礎上 增加封鎖
圖 7 事務A執行過程中 事務B無法插入 所以前後查詢結果一致
圖 8 事務B只能在事務A執行完畢後再執行 修改成功
圖 9 事務B執行後 學時資料被修改
第三題:設計一組操作產生丟失更新問題,然後通過封鎖避免丟失更新問題。
3.1概念:丟失更新我個人理解為事務A和事務B同時對該資料進行修改,假設事務A執行時間短,事務B執行時間長,那麼事務B會覆蓋事務A的修改結果。(換一種方式的放鴿子)
但是在SQL Server 2012中,不管是同一使用者還是不同使用者,都自帶鎖,即都是在先執行的事務執行完畢後,再執行另一個事務。
3.2總體思路 :
事務A先對學時資料查詢(原先為6),再對學時進行修改(修改為8),最後5秒等待期再次查詢(結果為8)。
事務B在事務A的等待期內開始執行(結果是等事務A結束再執行的),也先對學時資料查詢(原先為6),再對學時進行修改(修改為10),最後5秒等待期再次查詢(結果為10)
結果為事務B覆蓋了事務A的更新,可我覺得這只是因為事務B比事務A晚執行的原因
3.3 程式碼截圖:
圖 10 剛開始 學時資料為 6
先執行事務A,緊接著執行事務B(相當於在事務A的等待期內執行)
圖 11 可以視為 同時執行事務A和事務B
觀察事務A 、事務B的執行結果:
圖 12 事務A執行前資料為6 執行後資料為8
圖 13 事務B執行前資料為8 執行後資料為10 說明和事務A互不干擾
這時候我們可以發現,事務B在事務A全部完成之後再執行,對事務A互不干擾 ,最後檢視資料庫中的資料為10.
圖 14 資料庫 課程表中的資料
第四題:設計一組產生死鎖的操作,再利用相同順序法有效的避免死鎖。
4.1 概念 :就是你等我,我等你,導致互相一直等下去,卡死迴圈
4.2整體思路:
同樣 sql server 2012也自帶對死鎖的預防,實驗如下:
我先執行查詢1(操作1,等待5秒,操作2),然後馬上執行查詢2(操作2,等待5秒,操作1),因為執行中間有五秒等待時間,查詢1的第二個更新等待查詢2執行完畢,查詢2的第二個更新等待查詢1執行完畢,構成死鎖。
不過大概10秒鐘之後,sql server 2012自動解開了死鎖,即查詢2做出讓步,查詢1全部執行。( &^^^& 太智慧了)
4.3程式碼截圖:
圖 15 事務A被事務B讓步 成功執行
圖 16 事務B為了讓步事務A,成為犧牲品,後半段執行失敗
然後使用相同順序法調換順序之後:
圖 17 事務A正常執行
圖 18 事務B正常執行
即沒有死迴圈,正常執行。
6.實驗總結:
本次實驗學習了併發控制,目的是通過實驗瞭解四種異常事務狀態(分別是髒讀、不可重複讀、丟失更新、死鎖),理解發生異常事務狀態的原理,以及我們要則麼通過增加事務隔離級別來封鎖,實現併發控制。當然隨著事務隔離級別提升,所消耗的資源也變多,所以要根據實際情況選擇隔離級別,也要預防死鎖現象的發生。
當然sql server 2012版本自帶預防機制,所以導致部分實驗沒法做,但我覺得我們要學的重點是理解異常產生的原理,以及如何防止異常的發生。