1.髒讀:髒讀就是指當乙個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,另外乙個事務也訪問這個資料,然後使用了這個資料。
e.g.
1.mary的原工資為1000, 財務人員將mary的工資改為了8000(但未提交事務)
2.mary讀取自己的工資 ,發現自己的工資變為了8000,歡天喜地!
3.而財務發現操作有誤,回滾了事務,mary的工資又變為了1000
像這樣,mary記取的工資數8000是乙個髒資料。
2.不可重複讀:是指在乙個事務內,多次讀同一資料。在這個事務還沒有結束時,另外乙個事務也訪問該同一資料。那麼,在第乙個事務中的兩次讀資料之間,由於第二個事務的修改,那麼第乙個事務兩次讀到的的資料可能是不一樣的。這樣在乙個事務內兩次讀到的資料是不一樣的,因此稱為是不可重複讀。
e.g.
1.在事務1中,mary 讀取了自己的工資為1000,操作並沒有完成
2.在事務2中,這時財務人員修改了mary的工資為2000,並提交了事務.
3.在事務1中,mary 再次讀取自己的工資時,工資變為了2000
解決辦法:如果只有在修改事務完全提交之後才可以讀取資料,則可以避免該問題。
3.幻讀: 是指當事務不是獨立執行時發生的一種現象,例如第乙個事務對乙個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時,第二個事務也修改這個表中的資料,這種修改是向表中插入一行新資料。那麼,以後就會發生操作第乙個事務的使用者發現表中還有沒有修改的資料行,就好象發生了幻覺一樣。
e.g.
目前工資為1000的員工有10人。
1.事務1,讀取所有工資為1000的員工。
2.這時事務2向employee表插入了一條員工記錄,工資也為1000
3.事務1再次讀取所有工資為1000的員工 共讀取到了11條記錄,
解決辦法:如果在操作事務完成資料處理之前,任何其他事務都不可以新增新資料,則可避免該問題
不可重複讀的重點是修改:
同樣的條件, 你讀取過的資料,再次讀取出來發現值不一樣了
幻讀的重點在於新增或者刪除
同樣的條件, 第 1 次和第 2 次讀出來的記錄數不一樣
參考:2、在乙個程式中,依據事務的隔離級別將會有三種情況發生。
◆髒讀:乙個事務會讀進還沒有被另乙個事務提交的資料,所以你會看到一些最後被另乙個事務回滾掉的資料。
◆不可重複讀:乙個事務讀進一條記錄,另乙個事務更改了這條記錄並提交完畢,這時候第乙個事務再次讀這條記錄時,它已經改變了。
◆ 幻影讀:乙個事務用where子句來檢索乙個表的資料,另乙個事務插入一條新的記錄,並且符合where條件,這樣,第乙個事務用同乙個where條件來檢索資料後,就會多出一條記錄。
3、資料庫提供了四種事務隔離級別, 不同的隔離級別採用不同的鎖類開來實現.
在四種隔離級別中, serializable的級別最高, read uncommited級別最低.
大多數資料庫的預設隔離級別為: read commited,如sql server , oracle.
少數資料庫預設的隔離級別為repeatable read, 如mysql innodb儲存引擎
sql server鎖的機制
sql server的所有活動都會產生鎖。鎖定的單元越小,就越能越能提高併發處理能力,但是管理鎖的開銷越大。如何找到平衡點,使併發性和效能都可接受是sql server的難點。
sql server有如下幾種瑣:
sql server的所有活動都會產生鎖。鎖定的單元越小,就越能越能提高併發處理能力,但是管理鎖的開銷越大。如何找到平衡點,使併發性和效能都可接受是sql server的難點。
sql server有如下幾種瑣:
1、 共享鎖
用於唯讀操作(select),鎖定共享的資源。共享鎖不會阻止其他使用者讀,但是阻止其他的使用者寫和修改。
2、 更新鎖
更新鎖是一種意圖鎖,當乙個事務已經請求共享瑣後並試圖請求乙個獨佔鎖的時候發生更新瑣。例如當兩個事務在幾行資料行上都使用了共享鎖,並同時試圖獲取獨佔鎖以執行更新操作時,就發生了死鎖:都在等待對方釋放共享鎖而實現獨佔鎖。更新鎖的目的是只讓乙個事務獲得更新鎖,防止這種情況的發生。
3、 獨佔鎖
一次只能有乙個獨佔鎖用在乙個資源上,並且阻止其他所有的鎖包括共享縮。寫是獨佔鎖,可以有效的防止』髒讀』。
4、 意圖縮
在使用共享鎖和獨佔鎖之前,使用意圖鎖。從表的層次上檢視意圖鎖,以判斷事務能否獲得共享鎖和獨佔鎖,提高了系統的效能,不需從頁或者行上檢查。
5、 計畫鎖
sch-m,sch-s。對資料庫結構改變時用sch-m,對查詢進行編譯時用sch-s。這兩種鎖不會阻塞任何事務鎖,包括獨佔鎖。
讀是共享鎖,寫是排他鎖,先讀後更新的操作是更新鎖,更新鎖成功並且改變了資料時更新鎖公升級到排他鎖
l default 使用資料庫設定的隔離級別 ( 預設 ) ,由 dba 預設的設定來決定隔離級別 .
l read_uncommitted 會出現髒讀、不可重複讀、幻讀 (隔離級別最低,併發效能高)
l read_committed 會出現不可重複讀、幻讀問題(鎖定正在讀取的行)
l repeatable_read 會出幻讀(鎖定所讀取的所有行)
l serializable 保證所有的情況不會發生(鎖表)
readcommitted:
假設a事務對正在讀取資料data放置了共享鎖,那麼data不能被其它事務改寫,所以當b事務對data進行讀取時總和a讀取的data資料是一致的,所以避免了髒讀。由於在a沒有提交之前可以對data進行改寫,那麼b讀取到的某個值可能會在其讀取後被a更改從而導致了該值不能被重複取得;或者當b再次用相同的where字句時得到了和前一次不一樣資料的結果集,也就是幻像資料。
readuncommitted:
假設a事務即不發布共享鎖,也不接受獨佔鎖,那麼併發的b或者其它事務可以改寫a事務讀取的資料,那麼併發的c事務讀取到的資料的狀態和a的或者b的資料都可能不一致,那麼。髒讀、不可重複讀、幻象資料都可能存在。
repeatableread:
(注意msdn原文中的第一句話:在查詢中使用的所有資料上放置鎖,所以不存在髒讀的情況)。
假設a事務對讀取的所有資料data放置了鎖,以阻止其它事務對data的更改,在a沒有提交之前,新的併發事務讀取到的資料如果存在於data中,那麼該資料的狀態和a事務中的資料是一致的,從而避免了不可重複的讀取。但在a事務沒有結束之前,b事務可以插入新記錄到data所在的表中,那麼其它事務再次用相同的where字句查詢時,得到的結果數可能上一次的不一致,也就是幻像資料。
serializable:
在資料表上放置了排他鎖,以防止在事務完成之前由其他使用者更新行或向資料集中插入行,這是最嚴格的鎖。它防止了髒讀、不可重複讀取和幻象資料。
事務隔離級及髒讀 幻讀和不可重複讀
定義 是資料庫操作的最小工作單元,獨立不可分割,要麼都執行 要麼都不執行。1 原子性 強調事務的不可分割。2 一致性 事務開始之前和結束以後,資料庫的完整性約束沒有被破壞。3 隔離性 併發執行的各個事務之間不能互相干擾。4 永續性 事務一旦提交,資料就持久化到資料庫。資料庫事務的隔離級別有4種,由低...
事務 髒讀 不可重複讀 幻讀
建立db8資料庫 create database db8 使用db8資料庫 use db8 建立賬戶表 create table account id int primary keyauto increment 賬戶id name varchar 20 賬戶名稱 money double 賬戶餘額 ...
髒讀,不可重複讀,幻讀
髒讀,不可重複讀,幻讀是由於資料庫事務的隔離性導致的問題。髒讀 乙個事務讀取到了其它未提交事務操作的記錄。不可重複讀 乙個事務a內,首次查詢到一條相同記錄,然後事務b修改該條記錄並提交,事務a再次執行相同查詢,得到了事務b更新後的結果,事務a兩次相同的查詢,卻得到了不同的結果,這個叫做不可重複讀。是...