Oracle與SQL Server事務處理的比較

     事務處理是全部大型數據庫產品的一個關鍵問題,各數據庫廠商都在這個方面花費了很大精力,不一樣的事務處理方式會致使數據庫性能和功能上的巨大差別。事務處理也是數據庫管理員與數據庫應用程序開發人員必須深入理解的一個問題,對這個問題的疏忽可能會致使應用程序邏輯錯誤以及效率低下。
     下面咱們針對Oracle及SQL Server這兩種當前普遍使用的大型數據庫產品,探討一下它們在事務處理方面的一些差別。如沒有特殊說明,本文內容適用的數據庫產品版本爲Oracle9i及SQL Server 2000,其中的示例SQL語句,對於Oracle是在SQL*Plus中執行,而對於SQL Server 2000是在osql中執行。sql


1. 事務的概念
  事務能夠看做是由對數據庫的若干操做組成的一個單元,這些操做要麼都完成,要麼都取消,從而保證數據知足一致性的要求。事務的一個典型例子是銀行中的轉賬操做,賬戶A把必定數量的款項轉到賬戶B上,這個操做包括兩個步驟,一個是從賬戶A上把存款減去必定數量,二是在賬戶B上把存款加上相同的數量。這兩個步驟顯然要麼都完成,要麼都取消,不然銀行就會受損失。顯然,這個轉賬操做中的兩個步驟就構成一個事務。
數據庫中的事務還有以下ACID特徵。
  ACID分別是四個英文單詞的首寫字母,這四個英文單詞是Atomicity、Consistency、Isolation、Durability,分別翻譯爲原子性、一致性、隔離性、持久性。
    原子性:指事務中的操做,或者都完成,或者都取消。
    一致性:指事務中的操做保證數據庫中的數據不會出現邏輯上不一致的狀況,一致性通常會隱含的包括在其餘屬性之中。
    隔離性:指當前的事務與其餘未完成的事務是隔離的。在不一樣的隔離級別下,事務的讀取操做,能夠獲得的結果是不一樣的。
    持久性:指對事務發出COMMIT命令後,即便這時發生系統故障,事務的效果也被持久化了。與此相反的是,當在事務執行過程當中,系統發生故障,則事務的操做都被回滾,即數據庫回到事務開始以前的狀態。
  對數據庫中的數據修改都是在內存中完成的,這些修改的結果可能已經寫到硬盤也可能沒有寫到硬盤,若是在操做過程當中,發生斷電或系統錯誤等故障,數據庫能夠保證未結束的事務對數據庫的數據修改結果即便已經寫入磁盤,在下次數據庫啓動後也會被所有撤銷;而對於結束的事務,即便其修改的結果還未寫入磁盤,在數據庫下次啓動後會經過事務日誌中的記錄進行「重作」,即把丟失的數據修改結果從新生成,並寫入磁盤,從而保證結束事務對數據修改的永久化。這樣也保證了事務中的操做要麼所有完成,要麼所有撤銷。數據庫


2. 事務設置及類型的區別
  在SQL Server中有三種事務類型,分別是:隱式事務、顯式事務、自動提交事務,缺省爲自動提交。
  自動提交:是指對於用戶發出的每條SQL語句,SQL Server都會自動開始一個事務,而且在執行後自動進行提交操做來完成這個事務,也能夠說在這種事務模式下,一個SQL語句就是一個事務。
  顯式事務:是指在自動提交模式下以Begin Transaction開始一個事務,以Commit或Rollback結束一個事務,以Commit結束事務是把事務中的修改永久化,即便這時發生斷電這樣的故障。例以下面是SQL Server中的一個顯式事務的例子。
Begin Tran
   Update emp Set ename=’Smith’ Where empno=7369
   Insert Into dept Values(60,’HR’,’GZh’)
Commit
  隱式事務:是指在當前會話中用Set Implicit_Transactions On命令設置的事務類型,這時任何DML語句(Delete、Update、Insert)都會開始一個事務,而事務的結束也是用Commit或Rollback。
在Oracle中沒有SQL Server的這些事務類型,缺省狀況下任何一個DML語句都會開始一個事務,直到用戶發出Commit或Rollback操做,這個事務纔會結束,這與SQL Server的隱式事務模式類似。

3.  事務隔離級別
  在SQL92標準中,事務隔離級別分爲四種,分別爲:Read Uncommitted、Read Committed、Read Repeatable、Serializable,其中Read Uncommitted與Read Committed爲語句級別的,而Read Repeatable與Serializable是針對事務級別的。
  在Oracle和SQL Server中設置事務隔離級別的語句是相同的,都使用SQL92標準語法,即:Set Transaction Isolation Level Read Committed
  上面示例中的Read Committed能夠被替換爲其餘三種隔離級別中的任意一種。
  1) SQL Server中的隔離級別及實現機制
    在SQL Server中提供了全部這四種隔離級別。下面咱們討論在SQL Server中,這幾種隔離級別的含義及其實現方式。
    Read Uncommitted:一個會話能夠讀取其餘事務未提交的更新結果,若是這個事務最後以回滾結束,這時的讀取結果就多是錯誤的,因此多數的數據庫應用都不會使用這種隔離級別。
    Read Committed:這是SQL Server的缺省隔離級別,設置爲這種隔離級別的事務只能讀取其餘事務已經提交的更新結果,不然,發生等待,可是其餘會話能夠修改這個事務中被讀取的記錄,而沒必要等待事務結束,顯然,在這種隔離級別下,一個事務中的兩個相同的讀取操做,其結果可能不一樣。
    Read Repeatable:在一個事務中,若是在兩次相同條件的讀取操做之間沒有添加記錄的操做,也沒有其餘更新操做致使在這個查詢條件下記錄數增多,則兩次讀取結果相同。換句話說,就是在一個事務中第一次讀取的記錄保證不會在這個事務期間發生改變。SQL Server是經過在整個事務期間給讀取的記錄加鎖實現這種隔離級別的,這樣,在這個事務結束前,其餘會話不能修改事務中讀取的記錄,而只能等待事務結束,可是SQL Server不會阻礙其餘會話向表中添加記錄,也不阻礙其餘會話修改其餘記錄。
    Serializable:在一個事務中,讀取操做的結果是在這個事務開始以前其餘事務就已經提交的記錄,SQL Server經過在整個事務期間給表加鎖實現這種隔離級別。在這種隔離級別下,對這個表的全部DML操做都是不容許的,即要等待事務結束,這樣就保證了在一個事務中的兩次讀取操做的結果確定是相同的。
  2) Oracle中的隔離級別及實現機制
    在Oracle中,沒有Read Uncommitted及Repeatable Read隔離級別,這樣在Oracle中不容許一個會話讀取其餘事務未提交的數據修改結果,從而避免了因爲事務回滾發生的讀取錯誤。Oracle中的Read Committed和Serializable級別,其含義與SQL Server相似,可是實現方式卻大不同。
    在Oracle中,存在所謂的回滾段(Oracle9i以前版本)或撤銷段(Oracle9i版本),Oracle在修改數據記錄時,會把這些記錄被修改以前的結果存入回滾段或撤銷段中,就是由於這種機制,Oracle對於事務隔離級別的實現與SQL Server大相徑庭。在Oracle中,讀取操做不會阻礙更新操做,更新操做也不會阻礙讀取操做,這樣在Oracle中的各類隔離級別下,讀取操做都不會等待更新事務結束,更新操做也不會由於另外一個事務中的讀取操做而發生等待,這也是Oracle事務處理的一個優點所在。
    Oracle缺省的設置是Read Committed隔離級別(也稱爲語句級別的隔離),在這種隔離級別下,若是一個事務正在對某個表進行DML操做,而這時另一個會話對這個表的記錄進行讀取操做,則Oracle會去讀取回滾段或撤銷段中存放的更新以前的記錄,而不會象SQL Server同樣等待更新事務的結束。
    在Serializable隔離級別(也稱爲事務級別的隔離),事務中的讀取操做只能讀取這個事務開始以前已經提交的數據結果。若是在讀取時,其餘事務正在對記錄進行修改,則Oracle就會在回滾段或撤銷段中去尋找對應的原來未經更改的記錄(並且是在讀取操做所在的事務開始以前存放於回滾段或撤銷段的記錄),這時讀取操做也不會由於相應記錄被更新而等待。

4. DDL語句對事務的影響
  1) Oracle中DDL語句對事務的影響
  在Oracle中,執行DDL語句(如Create Table、Create View等)時,會在執行以前自動發出一個Commit命令,並在隨後發出一個Commit或者Rollback命令,也就是說,DDL會象以下僞碼同樣執行:
Commit;
DDL_Statement;
If (Error) then
   Rollback;
Else
   Commit;
End if;
  咱們經過分析下面例子來看Oracle中,DDL語句對事務的影響:
Insert into some_table values(‘Before’);
Creaate table T(x int);
Insert into some_table values(‘After’);
Rollback;
  因爲在Oracle執行Create table語句以前進行了提交,而在Create table執行後也會自動發出Commit命令,因此只有插入After的行被回滾,而插入Before的行不會被回滾,Create table命令的結果也不會被回滾,即便Create table語句失敗,所進行的Before插入也會被提交。若是最後發出Commit命令,由於插入Before及Create table的操做結果已經在以前提交,因此Commit命令影響的只有插入After的操做。
  2) SQL Server中DDL語句對事務的影響
在SQL Server中,DDL語句對事務的影響與其餘DML語句相同,也就是說,在DML語句發出以前或以後,都不會自動發出Commit命令。
在SQL Server 2000中,對於與上面Oracle一樣的例子,最後發出Rollback後,數據庫會回滾到插入Before以前的狀態,即插入Before和After的行都會被回滾,數據表T也不會被建立。
若是最後發出Commit操做,則會把三個操做的結果所有提交。

5.用戶斷開數據庫鏈接對事務的影響
另外,對應於Oracle的管理客戶端工具SQL*Plus,在SQL Server 2000中是osql,兩種管理工具都是命令行工具,使用方式及做用也相似,可是在SQL*Plus中,用戶退出鏈接時,會自動先發出Commit命令,而後再退出,而在osql中,若是用戶退出鏈接,會自動發出Rollback命令,這對於SQL Server的自動提交模式沒有什麼影響,但若是處於隱式事務模式,其影響是顯而易見的。對於兩種數據庫產品的其餘客戶端管理工具也有相似的不一樣之處。工具

相關文章
相關標籤/搜索