C 資料庫事務原理及實踐 上

2021-04-12 17:15:41 字數 4913 閱讀 8259

本文將涉及到在

.net

框架下使用

c#語言操縱資料庫事務的各個方面。

體驗sql語言的事務機制

作為大型的企業級資料庫,

sql server2000

對事務提供了很好的支援。我們可以使用

sql語句來定義、提交以及回滾乙個事務。

如下所示的

sql**定義了乙個事務,並且命名為

"mytransaction"

(限於篇幅,本文並不討論如何編寫

sql

declare @tranname varchar(20)

select @tranname = 'mytransaction'

begin transaction @trannamegouse pubs

goupdate roysched

set royalty = royalty * 1.10

where title_id like 'pc%'

gocommit transaction mytransactiongo

這裡用到了

sql server2000

自帶的示例資料庫

pubs

,提交事務後,將為所有暢銷計算機書籍支付的版稅增加

10%。

開啟

sql server2000

的查詢分析器,選擇

pubs

資料庫,然後執行這段程式,結果顯而易見。

可是如何在

c#程式中執行呢?我們記得在普通的

sql查詢中,一般需要把查詢語句賦值給

salcommand.commandtext

屬性,這裡也就像普通的

sql查詢語句一樣,將這些語句賦給

sqlcommand.commandtext

屬性即可。要注意的一點是,其中的

"go"

語句標誌著

sql批處理的結束,編寫

sql指令碼是需要的,但是在這裡是不必要的。我們可以編寫如下的程式來驗證這個想法:

//transql.csusing system;

using system.data;

using system.data.sqlclient;

namespace aspcn

catch(exception err)

finally

}file://

獲取資料連線

private sqlconnection getconn()

}public class test}}

注意到其中的

sqlcommand

物件mycomm

,它的commandtext

屬性僅僅是前面

sql**字串連線起來即可,當然,其中的

"go"

語句已經全部去掉了。這個語句就像普通的查詢一樣,程式將

sql文字事實上提交給

dbms

去處理了,然後接收返回的結果(如果有結果返回的話)。

很自然,我們最後看到了輸出

"事務處理已經成功完成

",再用企業管理器檢視

pubs

資料庫的

roysched

表,所有

title_id

欄位以"pc"

開頭的書籍的

royalty

欄位的值都增加了

0.1倍。

這裡,我們並沒有使用

ado.net

的事務處理機制,而是簡單地將執行事務的

sql語句當作普通的查詢來執行,因此,事實上該事務完全沒有用到

.net

的相關特性。

了解.net

中的事務機制

如你所知,在

.net

框架中主要有兩個命名空間

(namespace)

用於應用程式同資料庫系統的互動:

system.data.sqlclient

和system.data.oledb

。前者專門用於連線

microsoft

公司自己的

sql server

資料庫,而後者可以適應多種不同的資料庫。這兩個命名空間中都包含有專門用於管理資料庫事務的類,分別是

system.data.sqlclient.sqltranscation

類和system.data.oledb.oledbtranscation

類。

就像它們的名字一樣,這兩個類大部分功能是一樣的,二者之間的主要差別在於它們的連線機制,前者提供一組直接呼叫

sql server

的物件,而後者使用本機

ole db

啟用資料訪問。

事實上,

ado.net

事務完全在資料庫的內部處理,且不受

microsoft

分布式事務處理協調器

(dtc)

或任何其他事務性機制的支援。本文將主要介紹

system.data.sqlclient.sqltranscation

類,下面的段落中,除了特別註明,都將使用

system.data.sqlclient.sqltranscation

類。

事務的開啟和提交

現在我們對事務的概念和原理都了然於心了,並且作為已經有一些基礎的

c#開發者,我們已經熟知編寫資料庫互動程式的一些要點,即使用

sqlconnection

類的物件的

open()

方法建立與資料庫伺服器的連線,然後將該連線賦給

sqlcommand

物件的connection

屬性,將欲執行的

sql語句賦給它的

commandtext

屬性,於是就可以通過

sqlcommand

物件進行資料庫操作了。對於我們將要編寫的事務處理程式,當然還需要定義乙個

sqltransaction

型別的物件。並且看到

sqlcommand

物件的transcation

屬性,我們很容易想到新建的

sqltransaction

物件應該與它關聯起來。

基於以上認識,下面我們就開始動手寫我們的第乙個事務處理程式。我們可以很熟練地寫出下面這一段程式:

//dotran.csusing system;

using system.data;

using system.data.sqlclient;

namespace aspcn

catch(exception err)

finally

}file://

獲取資料連線

private sqlconnection getconn()

}public class test}}

顯然,這個程式非常簡單,我們非常自信地編譯它,但是,出乎意料的結果使我們的成就感頓時煙消雲散:

error cs1501:

過載"sqltransaction"

方法未獲取

"0"引數

是什麼原因呢?注意到我們初始化的**:

sqltransaction mytran=new sqltransaction();

顯然,問題出在這裡,事實上,

sqltransaction

類並沒有公共的建構函式,我們不能這樣新建乙個

sqltrancaction

型別的變數。在事務處理之前確實需要有乙個

sqltransaction

型別的變數,將該變數關聯到

sqlcommand

類的transcation

屬性也是必要的,但是初始化方法卻比較特別一點。在初始化

sqltransaction

類時,你需要使用

sqlconnection

類的begintranscation()

方法:

sqltransaction mytran; mytran=myconn.begintransaction();

該方法返回乙個

sqltransaction

型別的變數。在呼叫

begintransaction()

方法以後,所有基於該資料連線物件的

sql語句執行動作都將被認為是事務

mytran

的一部分。同時,你也可以在該方法的引數中指定事務隔離級別和事務名稱,如:

sqltransaction mytran;

mytran=myconn.begintransaction(isolationlevel.readcommitted,"sampletransaction");

關於隔離級別的概念我們將在隨後的內容中**,在這裡我們只需牢記乙個事務是如何被啟動,並且關聯到特定的資料鏈結的。

先不要急著去搞懂我們的事務都幹了些什麼,看到這一行:

mytran.commit();

是的,這就是事務的提交方式。該語句執行後,事務的所有資料庫操作將生效,並且為資料庫事務的永續性機制所保持

--即使系統在這以後發生致命錯誤,該事務對資料庫的影響也不會消失。

對上面的程式做了修改之後我們可以得到如下**(為了節約篇幅,重複之處已省略,請參照前文):

//dotran.cs……

}file://

執行事務處理

public void dotran()

catch(exception err)

finally}……

到此為止,我們僅僅掌握了如何開始和提交事務。下一步我們必須考慮的是在事務中可以幹什麼和不可以幹什麼。

C 資料庫事務原理及實踐

什麼是資料庫事務 資料庫事務是指作為單個邏輯工作單元執行的一系列操作。設想網上購物的一次交易,其付款過程至少包括以下幾步資料庫操作 更新客戶所購商品的庫存資訊 儲存客戶付款資訊 可能包括與銀行系統的互動 生成訂單並且儲存到資料庫中 更新使用者相關資訊,例如購物數量等等 正常的情況下,這些操作將順利進...

C 資料庫事務原理

隔離級別的概念 企業級的資料庫每一秒鐘都可能應付成千上萬的併發訪問,因而帶來了併發控制的問題。由資料庫理論可知,由於併發訪問,在不可預料的時刻可能引發如下幾個可以預料的問題 髒讀 包含未提交資料的讀取。例如,事務1 更改了某行。事務2 在事務1 提交更改之前讀取已更改的行。如果事務1 回滾更改,則事...

資料庫事務及實現

一 事務 事務指的是滿足acid特性的一組操作,可以通過 commit提交乙個事務,也可以使用 rollback 進行回滾。mysql 預設採用自動提交模式。也就是說,如果不顯式使用start transaction語句來開始乙個事務,那麼每個查詢都會被當做乙個事務自動提交。acid 1.原子性 a...