SQL Server和Oracle中交易處理的特點
1 事務的特徵(ACID屬性)
n Atomic原子性就是事務應作為一個工作單元,交易處理完成,所有的工作要麼都在資料庫中儲存下來,要麼完全復原,全部不保留。
n Consistent一致性 指事務中的操作保證資料庫中的資料不會出現邏輯上不一致的情況,一致性一般會隱含的包括在其他屬性之中。
n Isolated隔離性多個事務同時進行,它們之間應該互不干擾。應該防止一個交易處理其他事務也要修改的資料時,不合理的存取和不完整的讀取資料。
n Durable永久性事務提交以後,所做的工作就被永久的儲存下來。
2 事務的模式和開始結束時機
Ø SQL Server
n 自動事務
是指對於使用者發出的每條SQL語句,SQL Server都會自動開始一個事務,並且在執行後自動進行提交操作來完成這個事務,也可以說在這種事務模式下,一個SQL語句就是一個事務。
可以這麼理解,自動事務中每個DML或者DDL語句最後轉化為下面的語句執行
BEGIN
Commit
DML/DDL
Commit (當DML/DDL錯誤時Rollback)
END
n 隱含交易
在當前會話中使用SET IMPLICIT_TRANSACTIONS ON/OFF可以啟用/停止隱含交易。隱含交易從SET IMPLICIT_TRANSACTIONS ON後的第一個DML語句(資料動作陳述式,如insert、update、delete等)DDL語句(資料結構字典語句,如Alter、Create等)開始事務,在使用者commit或者rollback後結束事務。
n 明確交易/使用者定義事務
通過Begin transaction顯示開始事務,commit/rollback提交或者復原事務。
Ø Oracle
Oracle沒有像SQL Server一樣定義事務,沒有transaction關鍵字。其事務都是由DML/DDL語句自動開始的,通過顯示的Commit/Rollback提交/復原。
Select語句不是嚴格意義的DML,在SQL Server他不會開始事務,因此只能通過Begin Transaction在Select之前開始事務。在Oracle中,由於沒有顯示的事務開始方式,此方法行不通,怎麼辦呢?Select的For Update子句可以使Oracle中的該Select語句隱式開啟事務。
For Update子句還有一個重要的用途就是在SQL Server和Oracle中定義可修改的遊標。
3 事務的隔離等級
3.1 並發的不利影響
n 更新丟失(lost update):事務A並不知道在他執行的過程中事務B已經對一個記錄進行了修改,這時如果A也修改該記錄,則事務B的修改可能丟失。
n 髒讀(dirty read):事務中讀到了其他事務尚未提交的資料;
n 不可重複讀取(nonrepeatable read):由於受到其他並行事務的影響,本事務先後讀取同一資料得到了不同的結果(記錄被修改過)。
n 幻讀(phantom read):由於受到其他並行事務的影響,本事務先後讀取同一資料得到了不同的結果(結果中出現了新的記錄)。
3.2 並發控制
並發控制的技術很多,最重要的是鎖機制。各種資料庫系統實現的鎖機制都大同小異,本文對鎖機制不詳細介紹。
3.3 ANSI定義的4種交易隔離等級
n READ UNCOMMITTED :一個會話可以讀取其他事務未提交的更新結果,如果這個事務最後以復原結束,這時的讀取結果就可能是錯誤的,所以多數的資料庫應用都不會使用這種隔離等級。
n READ COMMITTED :這是SQL Server的預設隔離等級,設定為這種隔離等級的事務只能讀取其他事務已經提交的更新結果,否則,發生等待,但是其他會話可以修改這個事務中被讀取的記錄,而不必等待事務結束,顯然,在這種隔離等級下,一個事務中的兩個相同的讀取操作,其結果可能不同。
n REPEATABLE READ :在一個事務中,如果在兩次相同條件的讀取操作之間沒有添加記錄的操作,也沒有其他更新操作導致在這個查詢條件下記錄數增多,則兩次讀取結果相同。換句話說,就是在一個事務中第一次讀取的記錄保證不會在這個事務期間發生改變。SQL Server是通過在整個事務期間給讀取的記錄加鎖實現這種隔離等級的,這樣,在這個事務結束前,其他會話不能修改事務中讀取的記錄,而只能等待事務結束,但是SQL Server不會阻礙其他會話向表中添加記錄,也不阻礙其他會話修改其他記錄。
n SERIALIZABLE:簡單地說,SERIALIZABLE就是使事務看起來象是一個接著一個地順序地執行。比如事務A和事務B並發執行,則根據TA和TB提交的先後,資料庫中的資料必然先後出現兩個時刻:A提交後和B提交後,這兩個時刻資料都應該是完整的,正確的,且每個時刻的資料只和該事務開始時候的資料和事務的邏輯有關,與是否有其他事務正在執行無關。
3.4 SQL Server中的隔離等級
SQL Server中實現了ANSI定義的4種隔離等級,同時還增加了下面的兩個層級:
n READ_COMMITTED_SNAPSHOT :如果事務A對資料進行了修改但尚未提交,事務B試圖讀取這些資料時將根據事務B的隔離等級發生:
u READ COMMITTED:等待事務A提交後才能讀取;
u READ_COMMITTED_SNAPSHOT:忽略事務A對資料的更新,讀取最後已提交的資料版本;
n ALLOW_SNAPSHOT_ISOLATION :如果事務A以REPEATABLE READ隔離等級進行,事務A讀取了一些資料,則A將鎖定這些資料以保證可重複讀,其他事務只能等待A提交或者復原。而如果A以ALLOW_SNAPSHOT_ISOLATION進行,則其他事務不必等待且可以更新這些資料,同時保證事務A的可重複讀。
3.5 Oracle中的隔離等級
Oracle只實現了ANSI定義的4種隔離等級中的READ COMMITTED和SERIALIZABLE。