sql數(shù)據(jù)庫事務機制詳解_第1頁
sql數(shù)據(jù)庫事務機制詳解_第2頁
sql數(shù)據(jù)庫事務機制詳解_第3頁
sql數(shù)據(jù)庫事務機制詳解_第4頁
sql數(shù)據(jù)庫事務機制詳解_第5頁
免費預覽已結束,剩余1頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、事務機制什么叫事務?同步發(fā)生數(shù)據(jù)更新時,防止數(shù)據(jù)的不一致。這些就是數(shù)據(jù)庫特有的術語了。數(shù)據(jù)庫事務是指作為單個邏輯工作單元執(zhí)行的一系列操作。設想網上購物的一次交易,其付款過程至少包括以下幾步數(shù)據(jù)庫操作: 更新客戶所購商品的庫存信息 保存客戶付款信息 -可能包括與銀行系統(tǒng)的交互 生成訂單并且保存到數(shù)據(jù)庫中 更新用戶相關信息,例如購物數(shù)量等等正常的情況下,這些操作將順利進行,最終交易成功,與交易相關的所有數(shù)據(jù)庫信息也成功地 更新。但是,如果在這一系列過程中任何一個環(huán)節(jié)出了差錯,例如在更新商品庫存信息時發(fā)生異常、 該顧客銀行帳戶存款不足等,都將導致交易失敗。一旦交易失敗,數(shù)據(jù)庫中所有信息都必須保持交

2、易前的狀態(tài)不變,比如最后一步更新用戶信息時失敗而導致交易失敗,那么必須保證這筆失敗的交 易不影響數(shù)據(jù)庫的狀態(tài)-庫存信息沒有被更新、用戶也沒有付款,訂單也沒有生成。否則,數(shù)據(jù)庫的信息將會一片混亂而不可預測。數(shù)據(jù)庫事務正是用來保證這種情況下交易的平穩(wěn)性和可預測性的技術。數(shù)據(jù)庫事務的 ACID屬性事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數(shù)據(jù)的資 源。通過將一組相關操作組合為一個要么全部成功要么全部失敗的單元,可以簡化錯誤恢復并使應 用程序更加可靠。一個邏輯工作單元要成為事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性: 原子性事務必須是原子工作單元

3、;對于其數(shù)據(jù)修改,要么全都執(zhí)行,要么全都不執(zhí)行。通常,與某個 事務關聯(lián)的操作具有共同的目標,并且是相互依賴的。如果系統(tǒng)只執(zhí)行這些操作的一個子集,則可 能會破壞事務的總體目標。原子性消除了系統(tǒng)處理操作子集的可能性。 一致性事務在完成時,必須使所有的數(shù)據(jù)都保持一致狀態(tài)。在相關數(shù)據(jù)庫中,所有規(guī)則都必須應用于事務的修改,以保持所有數(shù)據(jù)的完整性。事務結束時,所有的內部數(shù)據(jù)結構(如B樹索引或雙向鏈表)都必須是正確的。某些維護一致性的責任由應用程序開發(fā)人員承擔,他們必須確保應用程序 已強制所有已知的完整性約束。例如,當開發(fā)用于轉帳的應用程序時,應避免在轉帳過程中任意移 動小數(shù)點。 隔離性由并發(fā)事務所作的修改

4、必須與任何其它并發(fā)事務所作的修改隔離。事務查看數(shù)據(jù)時數(shù)據(jù)所處的 狀態(tài),要么是另一并發(fā)事務修改它之前的狀態(tài),要么是另一事務修改它之后的狀態(tài),事務不會查看 中間狀態(tài)的數(shù)據(jù)。這稱為可串行性,因為它能夠重新裝載起始數(shù)據(jù),并且重播一系列事務,以使數(shù) 據(jù)結束時的狀態(tài)與原始事務執(zhí)行的狀態(tài)相同。當事務可序列化時將獲得最高的隔離級別。在此級別 上,從一組可并行執(zhí)行的事務獲得的結果與通過連續(xù)運行每個事務所獲得的結果相同。由于高度隔 離會限制可并行執(zhí)行的事務數(shù),所以一些應用程序降低隔離級別以換取更大的吞吐量。 持久性事務完成之后,它對于系統(tǒng)的影響是永久性的。該修改即使出現(xiàn)致命的系統(tǒng)故障也將一直保持。DBMS的責任和

5、我們的任務企業(yè)級的數(shù)據(jù)庫管理系統(tǒng)(DBMS )都有責任提供一種保證事務的物理完整性的機制。就常用的SQL Server2000系統(tǒng)而言,它具備鎖定設備隔離事務、記錄設備保證事務持久性等機制。因此,我們不必關心數(shù)據(jù)庫事務的物理完整性,而應該關注在什么情況下使用數(shù)據(jù)庫事務、事務對性能的 影響,如何使用事務等等。本文將涉及到在.net框架下使用 C#語言操縱數(shù)據(jù)庫事務的各個方面。體3金SQL語言的事務機制作為大型的企業(yè)級數(shù)據(jù)庫,SQL Server2000對事務提供了很好的支持。我們可以使用SQL語句來定義、提交以及回滾一個事務。如下所示的 SQL代碼定義了一個事務,并且命名為"MyTra

6、nsaction"(限于篇幅,本文并不討論如何編寫 SQL語言程序,請讀者自行參考相關書籍):DECLARE TranName VARCHAR(20)SELECT TranName = 'MyTransaction'BEGIN TRANSACTION TranNameGOUSE pubs GOUPDATE royschedSET royalty = royalty * 1.10WHERE title_id LIKE 'Pc%' GOCOMMIT TRANSACTION MyTransactionGO這里用到了 SQL Server2000 自帶的示例數(shù)

7、據(jù)庫 pubs ,提交事務后,將為所有暢銷計算機書籍 支付的版稅增加10%。打開SQL Server2000的查詢分析器,選擇 pubs數(shù)據(jù)庫,然后運行這段程序,結果顯而易見??墒侨绾卧?C#程序中運行呢?我們記得在普通的SQL查詢中,一般需要把查詢語句賦值給SalCommand.CommandText 屬性,這里也就像普通的SQL查詢語句一樣,將這些語句賦給SqlCommand.CommandText屬性即可。要注意的一點是,其中的 "GO"語句標志著 SQL批處理的結束,編寫SQL腳本是需要的, 但是在這里是不必要的。我們可以編寫如下的程序來驗證這個想法:/TranSq

8、l.csusing System;using System.Data;using System.Data.SqlClient;namespace Aspcnpublic class DbTranSqlfile:/將事務放到 SQL Server 中執(zhí)行public void DoTran() ( file:/建立連接并打開SqlConnection myConn=GetConn();myConn.Open();SqlCommand myComm=new SqlCommand(); try (myComm.Connection=myConn;myComm.CommandText="DE

9、CLARE TranName VARCHAR(20)" myComm.CommandText+="SELECT TranName = 'MyTransaction'" myComm.CommandText+="BEGIN TRANSACTION TranName " myComm.CommandText+="USE pubs "myComm.CommandText+="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE &

10、#39;Pc%' "myComm.CommandText+="COMMIT TRANSACTION MyTransaction " myComm.ExecuteNonQuery(); catch(Exception err) (throw new ApplicationException(" 事務操作出錯,系統(tǒng)信息:"+err.Message); finally (myConn.Close(); file:/獲取數(shù)據(jù)連接 private SqlConnection GetConn()(string strSql="Data S

11、ource=localhost;Integrated Security=SSPI;user id=sa;password=" SqlConnection myConn=new SqlConnection(strSql);return myConn; public class Test (public static void Main()(DbTranSql tranTest=new DbTranSql();tranTest.DoTran();Console.WriteLine("事務處理已經成功完成。");Console.ReadLine();注意到其中的 Sql

12、Command 對象 myComm ,它的CommandText 屬性僅僅是前面SQL代碼字符串連接起來即可,當然,其中的 "GO"語句已經全部去掉了。這個語句就像普通的查詢一樣,程序 將SQL文本事實上提交給DBMS去處理了,然后接收返回的結果(如果有結果返回的話)。很自然,我們最后看到了輸出"事務處理已經成功完成",再用企業(yè)管理器查看pubs數(shù)據(jù)庫的roysched 表,所有title_id字段以"PC”開頭的書籍的 royalty字段的值都增加了0.1倍。這里,我們并沒有使用ADO.net的事務處理機制,而是簡單地將執(zhí)行事務的SQL語句當

13、作普通的查詢來執(zhí)行,因此,事實上該事務完全沒有用到.net的相關特性。了解.net中的事務機制如你所知,在.net框架中主要有兩個命名空間(namespace)用于應用程序同數(shù)據(jù)庫系統(tǒng)的交互:System.Data.SqlClient 和 System.Data.OleDb 。前者專門用于連接Microsoft 公司自己的 SQLServer數(shù)據(jù)庫,而后者可以適應多種不同的數(shù)據(jù)庫。這兩個命名空間中都包含有專門用于管理數(shù)據(jù) 庫事務的類,分別是 System.Data.SqlClient.SqlTranscation 類和 System.Data.OleDb.OleDbTranscation 類。

14、就像它們的名字一樣,這兩個類大部分功能是一樣的,二者之間的主要差別在于它們的連接機制,前者提供一組直接調用SQL Server的對象,而后者使用本機OLE DB 啟用數(shù)據(jù)訪問。事實上,ADO.net 事務完全在數(shù)據(jù)庫的內部處理,且不受 Microsoft 分布式事務處理協(xié)調器(DTC)或任何其他事務性機制的支持。本文將主要介紹System.Data.SqlClient.SqlTranscation 類,下面的段落中,除了特別注明,都將使用System.Data.SqlClient.SqlTranscation 類。事務的開啟和提交現(xiàn)在我們對事務的概念和原理都了然于心了,并且作為已經有一些基礎的

15、C#開發(fā)者,我們已經熟知編寫數(shù)據(jù)庫交互程序的一些要點,即使用SqlConnection 類的對象的 Open()方法建立與數(shù)據(jù)庫服務器的連接,然后將該連接賦給SqlCommand 對象的Connection 屬性,將欲執(zhí)行的 SQL語句賦給它的CommandText 屬性,于是就可以通過SqlCommand對象進行數(shù)據(jù)庫操作了。對于我們將要編寫的事務處理程序,當然還需要定義一個SqlTransaction類型的對象。并且看到SqlCommand對象的Transcation 屬性,我們很容易想到新建的SqlTransaction對象應該與它關聯(lián)起來?;谝陨险J識,下面我們就開始動手寫我們的第一個

16、事務處理程序。我們可以很熟練地寫出下 面這一段程序:/DoTran.csusing System;using System.Data;using System.Data.SqlClient;namespace Aspcn( public class DbTran ( file:/執(zhí)行事務處理 public void DoTran() ( file:/建立連接并打開 SqlConnection myConn=GetConn(); myConn.Open();SqlCommand myComm=new SqlCommand();SqlTransaction myTran=new SqlTransa

17、ction(); try ( myComm.Connection=myConn;myComm.Transaction=myTran; file:/定位到pubs數(shù)據(jù)庫 myComm.CommandText="USE pubs" myComm.ExecuteNonQuery();file:/更新數(shù)據(jù)file:/將所有的計算機類圖書myComm.CommandText="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%'"myComm.ExecuteNo

18、nQuery();/提交事務myTran.Commit(); catch(Exception err) ( throw new ApplicationException("事務操作出錯,系統(tǒng)信息: "+err.Message); finally ( myConn.Close(); file:/獲取數(shù)據(jù)連接 private SqlConnection GetConn() (string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password="SqlConnect

19、ion myConn=new SqlConnection(strSql); return myConn;) ) public class Testpublic static void Main() (DbTran tranTest=new DbTran();tranTest.DoTran();Console.WriteLine("事務處理已經成功完成。");Console.ReadLine();) ) )顯然,這個程序非常簡單,我們非常自信地編譯它,但是,出乎意料的結果使我們的成就感頓 時煙消云散:error CS1501: 重載"SqlTransaction&q

20、uot; 方法未獲取 "0"參數(shù) 是什么原因呢?注意到我們初始化的代碼:SqlTransaction myTran=new SqlTransaction();顯然,問題出在這里,事實上,SqlTransaction類并沒有公共的構造函數(shù),我們不能這樣新建一個SqlTrancaction 類型的變量。在事務處理之前確實需要有一個SqlTransaction 類型的變量,將該變量關聯(lián)到SqlCommand 類的Transcation屬性也是必要的,但是初始化方法卻比較特別一點。在初始化 SqlTransaction 類時,你需要使用SqlConnection 類的 BeginT

21、ranscation() 方法:SqlTransaction myTran; myTran=myConn.BeginTransaction();該方法返回一個SqlTransaction 類型的變量。在調用 BeginTransaction() 方法以后,所有基于該數(shù)據(jù)連接對象的SQL語句執(zhí)行動作都將被認為是事務MyTran的一部分。同時,你也可以在該方法的參數(shù)中指定事務隔離級別和事務名稱,如:SqlTransaction myTran;myTran=myConn.BeginTransaction(IsolationLevel.ReadCommitted,"SampleTransac

22、tion");關于隔離級別的概念我們將在隨后的內容中探討,在這里我們只需牢記一個事務是如何被啟動,并且關聯(lián)到特定的數(shù)據(jù)鏈接的。先不要急著去搞懂我們的事務都干了些什么,看到這一行: myTran.Commit();是的,這就是事務的提交方式。該語句執(zhí)行后,事務的所有數(shù)據(jù)庫操作將生效,并且為數(shù)據(jù)庫 事務的持久性機制所保持-即使系統(tǒng)在這以后發(fā)生致命錯誤,該事務對數(shù)據(jù)庫的影響也不會消失。對上面的程序做了修改之后我們可以得到如下代碼(為了節(jié)約篇幅,重復之處已省略,請參照 前文):/DoTran.cs file:/執(zhí)行事務處理public void DoTran()(file:/建立連接并打開SqlConnection myConn=GetCo

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論