事務四大特徵:原子性,一致性,隔離性和持久性(ACID),四大acid
一.事務
定義:所謂事務,它是一個操作序列,這些操作要麼都執行,要麼都不執行,它是一個不可分割的工作單位。
準備工作:為了說明事務的ACID原理,我們使用銀行賬戶及資金管理的案例進行分析。
[sql] view plaincopyprint?
- // 建立資料庫
- create table account(
- idint primary key not null,
- namevarchar(40),
- moneydouble
- );
-
- // 有兩個人開戶並存錢
- insert into account values(1,'A',1000);
- insert into account values(2,'B',1000);
二.ACID
ACID,是指在可靠資料庫管理系統(DBMS)中,事務(transaction)所應該具有的四個特性:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability).這是可靠資料庫所應具備的幾個特性.下面針對這幾個特性進行逐個講解.
三.原子性
原子性是指事務是一個不可再分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
1.案例
A給B轉帳100元錢
[sql] view plaincopyprint?
- begin transaction
- update account set money= money - 100where name='A';
- update account set money= money +100where name='B';
- if Error then
- rollback
- else
- commit
2.分析
在事務中的扣款和加款兩條語句,要麼都執行,要麼就都不執行。否則如果只執行了扣款語句,就提交了,此時如果突然斷電,A帳號已經發生了扣款,B帳號卻沒收到加款,在生活中就會引起糾紛。
3.解決方案
在資料庫管理系統(DBMS)中,預設情況下一條SQL就是一個單獨事務,事務是自動認可的。只有顯式的使用start transaction開啟一個事務,才能將一個代碼塊放在事務中執行。保障事務的原子性是資料庫管理系統的責任,為此許多資料來源採用日誌機制。例如,SQL Server使用一個預寫交易記錄,在將資料提交到實際資料頁面前,先寫在交易記錄上。
四.一致性
一致性是指在事務開始之前和事務結束以後,資料庫的完整性條件約束沒有被破壞。這是說資料庫事務不能破壞關係資料的完整性以及商務邏輯上的一致性。
1.案例
對銀行轉帳事務,不管事務成功還是失敗,應該保證事務結束後ACCOUNT表中aaa和bbb的存款總額為2000元。
2.解決方案
保障事務的一致性,可以從以下兩個層面入手
2.1資料庫機制層面
資料庫層面的一致性是,在一個事務執行之前和之後,資料會符合你設定的約束(唯一約束,外鍵約束,Check約束等)和觸發器設定。這一點是由SQL SERVER進行保證的。比如轉賬,則可以使用CHECK約束兩個賬戶之和等於2000來達到一致性目的
2.2業務層面
對於業務層面來說,一致性是保持業務的一致性。這個業務一致性需要由開發人員進行保證。當然,很多業務方面的一致性,也可以通過轉移到資料庫機制層面進行保證。
五.隔離性
多個事務並發訪問時,事務之間是隔離的,一個事務不應該影響其它事務運行效果。
這指的是在並發環境中,當不同的事務同時操縱相同的資料時,每個事務都有各自的完整資料空間。由並發事務所做的修改必須與任何其他並發事務所做的修改隔離。事務查看資料更新時,資料所處的狀態要麼是另一事務修改它之前的狀態,要麼是另一事務修改它之後的狀態,事務不會查看到中間狀態的資料。
在Windows中,如果多個進程對同一個檔案進行修改是不允許的,Windows通過這種方式來保證不同進程的隔離性:
企業開發中,事務最複雜問題都是由事務隔離性引起的。當多個事務並發時,SQL Server利用加鎖和阻塞來保證事務之間不同等級的隔離性。一般情況下,完全的隔離性是不現實的,完全的隔離性要求資料庫同一時間只執行一條事務,這樣會嚴重影響效能。想要理解SQL Server中對於隔離性的保障,首先要瞭解並發事務之間是如何幹擾的.
1.事務之間的相互影響
事務之間的相互影響分為幾種,分別為:髒讀,不可重複讀取,幻讀,丟失更新
1.1髒讀
髒讀意味著一個事務讀取了另一個事務未提交的資料,而這個資料是有可能復原的;如下案例,此時如果事務1復原,則B賬戶必將有損失。
1.2不可重複讀取
不可重複讀取意味著,在資料庫訪問中,一個事務範圍內兩個相同的查詢卻返回了不同資料。這是由於查詢時系統中其他事務修改的提交而引起的。如下案例,事務1必然會變得糊塗,不知道發生了什麼。
1.3幻讀(虛讀)
幻讀,是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時,第二個事務也修改這個表中的資料,這種修改是向表中插入一行新資料。那麼,以後就會發生操作第一個事務的使用者發現表中還有沒有修改的資料行,就好象發生了幻覺一樣.
1.4丟失更新
兩個事務同時讀取同一條記錄,A先修改記錄,B也修改記錄(B是不知道A修改過),B提交資料後B的修改結果覆蓋了A的修改結果。
2.理解SQL SERVER中的隔離等級
資料庫的交易隔離等級(TRANSACTION ISOLATION LEVEL)是一個資料庫上很基本的一個概念。為什麼會有交易隔離等級,SQL Server上實現了哪些交易隔離等級?交易隔離等級的前提是一個多使用者、多進程、多線程的並發系統,在這個系統中為了保證資料的一致性和完整性,我們引入了交易隔離等級這個概念,對一個單使用者、單線程的應用來說則不存在這個問題。
為了避免上述幾種事務之間的影響,SQL Server通過設定不同的隔離等級來進行不同程度的避免。因為高的隔離等級意味著更多的鎖,從而犧牲效能。所以這個選項開放給了使用者根據具體的需求進行設定。不過預設的隔離等級Read Commited符合了多數的實際需求.
隔離等級 |
髒讀 |
丟失更新 |
不可重複讀取 |
幻讀 |
並行存取模型 |
更新衝突檢測 |
未提交讀:Read Uncommited |
是 |
是 |
是 |
是 |
悲觀 |
否 |
已提交讀:Read commited |
否 |
是 |
是 |
是 |
悲觀 |
否 |
可重複讀:Repeatable Read |
否 |
否 |
否 |
是 |
悲觀 |
否 |
可串列讀:Serializable |
否 |
否 |
否 |
否 |
悲觀 |
否 |
SQL Server隔離事務之間的影響是通過鎖來實現的,通過阻塞來阻止上述影響。不同的隔離等級是通過加不同的鎖,造成阻塞來實現的,所以會以付出效能作為代價;安全層級越高,處理效率越低;安全層級越低,效率高。
使用方法:SET TRANSACTIONISOLATION LEVEL REPEATABLE READ
未提交讀: 在讀資料時不會檢查或使用任何鎖。因此,在這種隔離等級中可能讀取到沒有提交的資料。
已提交讀:唯讀取提交的資料並等待其他事務釋放獨佔鎖定。讀資料的共用鎖定在讀操作完成後立即釋放。已提交讀是SQL Server的預設隔離等級。
可重複讀: 像已提交讀層級那樣讀資料,但會保持共用鎖定直到事務結束。
可串列讀:工作方式類似於可重複讀。但它不僅會鎖定受影響的資料,還會鎖定這個範圍。這就阻止了新資料插入查詢所涉及的範圍。
六.持久性
持久性,意味著在事務完成以後,該事務所對資料庫所作的更改便持久的儲存在資料庫之中,並不會被復原。
即使出現了任何事故比如斷電等,事務一旦提交,則持久化儲存在資料庫中。
SQL SERVER通過write-ahead transaction log來保證持久性。write-ahead transaction log的意思是,事務中對資料庫的改變在寫入到資料庫之前,首先寫入到交易記錄中。而交易記錄是按照順序排號的(LSN)。當資料庫崩潰或者伺服器斷點時,重啟動SQL SERVER,SQLSERVER首先會檢查日誌順序號,將本應對資料庫做更改而未做的部分持久化到資料庫,從而保證了持久性。
七.總結
事務的(ACID)特性是由關聯式資料庫管理系統(RDBMS,資料庫系統)來實現的。資料庫管理系統採用日誌來保證事務的原子性、一致性和持久性。日誌記錄了事務對資料庫所做的更新,如果某個事務在執行過程中發生錯誤,就可以根據日誌,撤銷事務對資料庫已做的更新,使資料庫退回到執行事務前的初始狀態。
資料庫管理系統採用鎖機制來實現事務的隔離性。當多個事務同時更新資料庫中相同的資料時,只允許持有鎖的事務能更新該資料,其他事務必須等待,直到前一個事務釋放了鎖,其他事務才有機會更新該資料。