使用ADO.NET設(shè)置SQL Server事務(wù)處理
發(fā)表時(shí)間:2024-01-20 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]ADO.NET提供了處理后臺(tái)數(shù)據(jù)所需要的一切功能,并且使用起來(lái)就如同從一張表格中讀取一個(gè)數(shù)據(jù)那樣簡(jiǎn)單。事務(wù)處理(transaction)允許你把數(shù)據(jù)庫(kù)操作歸為一組,由此來(lái)保證所有的操作都能夠執(zhí)行。因?yàn)橐坏┢渲械囊豁?xiàng)操作執(zhí)行失敗,則整個(gè)事務(wù)處理都會(huì)失敗,F(xiàn)在讓我們來(lái)看看在.NET Framework...
ADO.NET提供了處理后臺(tái)數(shù)據(jù)所需要的一切功能,并且使用起來(lái)就如同從一張表格中讀取一個(gè)數(shù)據(jù)那樣簡(jiǎn)單。事務(wù)處理(transaction)允許你把數(shù)據(jù)庫(kù)操作歸為一組,由此來(lái)保證所有的操作都能夠執(zhí)行。因?yàn)橐坏┢渲械囊豁?xiàng)操作執(zhí)行失敗,則整個(gè)事務(wù)處理都會(huì)失敗,F(xiàn)在讓我們來(lái)看看在.NET Framework下是如何使用事務(wù)處理的。
事務(wù)處理概況
事務(wù)處理是把一組操作合并為一個(gè)邏輯上的工作單元。在系統(tǒng)中沒(méi)有出現(xiàn)錯(cuò)誤的情況下,開(kāi)發(fā)人員可以使用事務(wù)處理來(lái)控制并保持事務(wù)處理中每一個(gè)動(dòng)作的連續(xù)性和完整性。
使用這樣的方法可能導(dǎo)致向兩個(gè)極端情況發(fā)展:要么在事務(wù)處理中的所有操作都得到執(zhí)行,要么沒(méi)有任何操作得到執(zhí)行。這樣的方法對(duì)于實(shí)時(shí)應(yīng)用程序來(lái)說(shuō)非常必要。
銀行業(yè)務(wù)是一個(gè)范例。事務(wù)處理應(yīng)當(dāng)包括從一個(gè)帳戶到另一帳戶的轉(zhuǎn)帳過(guò)程。這一過(guò)程屬于事務(wù)處理,原因是從某帳戶中支出和在另一帳戶存入兩個(gè)動(dòng)作必須被作為一個(gè)整體來(lái)執(zhí)行——任何一方都不允許失敗。在深入研究ADO.NET編程之前,讓我們先來(lái)看看在SQL中是如何進(jìn)行事務(wù)處理的。
SQL事務(wù)處理
SQL允許開(kāi)發(fā)人員使用兩個(gè)簡(jiǎn)單的聲明來(lái)使用事務(wù)處理
Begin Transaction (啟動(dòng)事務(wù)處理)
Commit Transaction (提交事務(wù)處理)
在兩條聲明中的所有語(yǔ)句都成為事務(wù)處理的一部分。命令Begin Transaction位于整個(gè)事務(wù)處理的起始位置,因此其后的所有命令只有在執(zhí)行到命令Commit Transaction時(shí)才會(huì)被一并執(zhí)行。ADO.NET方法就這么簡(jiǎn)單。
ADO.NET事務(wù)處理
事務(wù)處理需要一個(gè)數(shù)據(jù)庫(kù)連接以及一個(gè)事務(wù)處理對(duì)象。在SQL Server和ADO.NET中使用事務(wù)處理的難點(diǎn)在于SqlTransaction類。此類名稱隨所使用的數(shù)據(jù)庫(kù)平臺(tái)的不同而會(huì)有一些變化。例如,對(duì)于OLEDB數(shù)據(jù)庫(kù)來(lái)說(shuō),事務(wù)處理類名為OleDbTransaction。
System.Data.SqlClient namespace包括了SqlTransaction類。此類包括了兩個(gè)屬性:
Connection:指示同事務(wù)處理相關(guān)聯(lián)的SqlConnection對(duì)象;
IsolationLevel:定義事務(wù)處理的IsolationLevel。
屬性IsolationLevel是包括如下成員的枚舉對(duì)象:
Chaos:從高度獨(dú)立的事務(wù)處理中出現(xiàn)的pending changes不能被覆蓋;
ReadCommitted:當(dāng)數(shù)據(jù)需要被非惡意讀取時(shí),采用共享鎖定(shared locks),但數(shù)據(jù)仍然可以在事務(wù)處理結(jié)束時(shí)被更新,這造成了非重復(fù)性的數(shù)據(jù)讀。╪onrepeatable reads)或phantom data的產(chǎn)生;
ReadUncommitted:惡意讀取數(shù)據(jù)是可能發(fā)生的,這表示沒(méi)有使用共享鎖定(shared locks),并且沒(méi)有實(shí)現(xiàn)獨(dú)占鎖定(exclusive locks);
RepeatableRead:鎖定查詢中所用到的所有數(shù)據(jù),由此避免其他用戶對(duì)數(shù)據(jù)進(jìn)行更新。在phantom rows仍然可用的狀態(tài)下,這可以避免非重復(fù)性的數(shù)據(jù)讀。╪onrepeatable reads);
Serialisable:在DataSet中進(jìn)行范圍鎖定,由此防止其他用戶在事務(wù)處理結(jié)束之前更新數(shù)據(jù)或在數(shù)據(jù)庫(kù)中插入行;
IsolationLevel定義鎖定記錄的級(jí)別,但這一概念不在本文論述范圍之內(nèi)。對(duì)象SqlTransaction也提供了類似的方法。你可以使用以下方法來(lái)進(jìn)行事務(wù)處理:
Commit:提交數(shù)據(jù)庫(kù)事務(wù)處理;
Rollback:從未決狀態(tài)(pending state)反轉(zhuǎn)(roll back)事務(wù)處理。事務(wù)處理一旦被提交后即不能執(zhí)行此操作;
Save:在事務(wù)處理中創(chuàng)建savepoint可以對(duì)事務(wù)處理的一部分進(jìn)行反轉(zhuǎn),并且指定savepoint名稱。
以下的C#示例將這些部分綜合起來(lái)。
這一簡(jiǎn)單的控制臺(tái)程序?qū)⑼ㄟ^(guò)以下步驟將兩行插入到Northwind數(shù)據(jù)庫(kù)的表格中:
調(diào)用Connection對(duì)象的BeginTransaction方法以標(biāo)記事務(wù)處理的起始位置。BeginTransaction方法對(duì)事務(wù)處理返回了一個(gè)坐標(biāo)(reference),此坐標(biāo)被指定給事務(wù)處理所用到的Command對(duì)象。
將Transaction對(duì)象指定給將要執(zhí)行的Command的Transaction屬性。如果某Command在活動(dòng)Transaction中的Connection上被執(zhí)行,并且Transaction對(duì)象還沒(méi)有被指定到Command的Transaction屬性,則會(huì)產(chǎn)生一個(gè)異常。
調(diào)用Transaction對(duì)象的Commit方法來(lái)結(jié)束事務(wù)處理,或者調(diào)用Rollback方法來(lái)取消事務(wù)處理。
等價(jià)的VB.NET代碼與之類似。
事務(wù)處理結(jié)束
盡管這是一個(gè)簡(jiǎn)單的示例,但它還是充分顯示了在.NET應(yīng)用程序中使用事務(wù)處理是多么的簡(jiǎn)單。請(qǐng)記住,事務(wù)處理只有在處理一組命令時(shí)才是必要的。