翻譯|使用教程|編輯:李爽夏|2019-01-22 10:48:14.000|閱讀 260 次
概述:本教程說明了從.NET代碼(不包含envolving PL/SQL事務)操作事務的方法。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
【下載dotConnect for Oracle最新版本】
dotConnect for Oracle(原名OraDirect.NET)建立在ADO.NET技術上,為基于Oracle數據庫的應用程序提供完整的解決方案。它為設計應用程序結構帶來了新的方法,提高工作效率,使數據庫應用程序的開發更簡便。
使用事務
事務是一個或多個被視為單個工作單元的操作,完全完成或完全無效(“全部或無”)。如果事務中某一點發生故障,則所有更新都可以回滾到其事務前狀態。事務必須符合ACID屬性-原子性、一致性、隔離性和持久性,以確保數據一致性。
如果一個事務涉及同一數據庫中的多個表,那么PL/SQL中的顯式事務通常執行得更好。您可以在SQL中使用Commit和Rollback語句分別修復和放棄當前PL/SQL塊中以前的命令。
否則,可以通過設計用于Oracle數據庫的庫/程序集中的特殊命令類來實現具有普通SQL的事務。例如,您可以使用devart.data.oracle.oraclecommand:在oraclecommand的連接上啟動事務,通過此oraclecommand執行多個SQL語句,并在必要時提交/回滾所有操作。請參閱本地事務主題中的示例。
本文描述了從.NET代碼(不包含envolving PL/SQL事務)操作事務的方法——這是處理事務最常見的情況。關于您的任務,您可以選擇要實現的事務類型-本地或分布式。當事務是單階段事務并且由數據庫直接處理時,被認為是本地事務的事務。分布式事務是一個影響多個資源的事務,它由事務監視器協調,并使用故障保護機制(如兩階段提交)來解決事務。
注意:Oracle不支持SQL Server中使用的可升級事務,分布式事務的實現在OCI和Direct模式下有所不同。還要考慮到TransactionScope(分布式事務)僅在處理時完成。
dotConnect for Oracle具有用于執行本地事務的OracleTransaction對象。當一個連接對象上的多個操作應作為一個事務執行時,使用OracleTransaction。應用程序通過對OracleConnection對象調用BeginTransaction來創建OracleTransaction對象。與事務相關聯的所有后續操作(例如,提交或中止事務)都在OracleTransaction對象上執行。OracleConnection和OracleTransaction之間的相關性始終為1:1。因此,一次只能為單獨的OracleConnection創建一個OracleTransaction。
例子:
下面的示例創建OracleConnection和OracleTransaction。它還演示了如何使用BeginTransaction、Commit和Rollback方法。
public void RunOracleTransaction(string myConnString) { OracleConnection myConnection = new OracleConnection(myConnString); myConnection.Open(); OracleCommand myCommand = new OracleCommand(); OracleTransaction myTrans; // Start a local transaction myTrans = myConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted); // Assign transaction object for a pending local transaction myCommand.Transaction = myTrans; myCommand.Connection = myConnection; try { myCommand.CommandText = "INSERT INTO Test.Dept(DeptNo, DName) Values(50, 'DEVELOPMENT')"; myCommand.ExecuteNonQuery(); myCommand.CommandText = "INSERT INTO Test.Dept(DeptNo, DName) Values(60, 'PRODUCTION')"; myCommand.ExecuteNonQuery(); myTrans.Commit(); Console.WriteLine("Both records are written to database."); } catch(Exception e) { myTrans.Rollback(); Console.WriteLine(e.ToString()); Console.WriteLine("Neither record was written to database."); } finally { myConnection.Close(); } }
Public Sub RunOracleTransaction(ByVal myConnString As String) Dim myConnection As New OracleConnection(myConnString) myConnection.Open() Dim myCommand As New OracleCommand Dim myTrans As OracleTransaction ' Start a local transaction myTrans = myConnection.BeginTransaction(System.Data.IsolationLevel.ReadCommitted) ' Assign transaction object for a pending local transaction myCommand.Transaction = myTrans myCommand.Connection = myConnection Try myCommand.CommandText = "INSERT INTO Test.Dept(DeptNo, DName) Values(50, 'DEVELOPMENT')" myCommand.ExecuteNonQuery() myCommand.CommandText = "INSERT INTO Test.Dept(DeptNo, DName) Values(60, 'PRODUCTION')" myCommand.ExecuteNonQuery() myTrans.Commit() Console.WriteLine("Both records are written to database.") Catch e As Exception myTrans.Rollback() Console.WriteLine(e.ToString()) Console.WriteLine("Neither record was written to database.") Finally myConnection.Close() End Try End Sub
如果要將對多個連接對象執行的操作放入同一分布式事務中,則需要將它們登記到TransactionScope中。它可以通過連接字符串的Enlist參數或OracleConnection類的Enlist Transaction方法來完成。
OCI模式完全支持TransactionScope和兩階段提交。
System.Transactions.TransactionScope類通過在分布式事務中隱式登記連接,使代碼塊成為事務性的。必須在TransactionScope標記的代碼塊末尾調用完整方法。當程序執行離開代碼塊時調用Dispose方法,如果不調用完整方法,則會導致事務中斷。如果引發了導致代碼離開作用域的異常,則認為該事務已中止。
建議使用using塊以確保在退出using塊時對TransactionScope對象調用Dispose方法。提交或回滾掛起的事務失敗會嚴重降低性能,因為TransactionScope的默認超時為一分鐘。如果不使用using語句,則必須在try塊中執行所有工作,并在finally塊中顯式調用Dispose方法。
如果TransactionScope內發生異常,則該事務將標記為不一致并被放棄。在釋放TransactionScope時回滾。如果沒有發生異常,則參與事務提交。
例子:
下面的示例演示TransactionScope的用法。必須添加對System.Transactions.dll程序集的引用,才能使用System.Transactions命名空間。
using (TransactionScope transScope = new TransactionScope()) { using (OracleConnection connection1 = new OracleConnection(connectString1)) { // Opening connection1 automatically enlists it in the // TransactionScope as a distributed transaction. connection1.Open(); // Do work in the first connection. // Assumes conditional logic in place where the second // connection will only be opened as needed. using (OracleConnection connection2 = new OracleConnection(connectString2)) { // Open the second connection, which enlists the // second connection to a full distributed transaction. connection2.Open(); // Do work in the second connection. } } // The Complete method commits the transaction. transScope.Complete(); // The result of transaction will be available at the database after // disposing TransactionScope }
Using transScope As New TransactionScope() Using connection1 As New OracleConnection(connectString1) ' Opening connection1 automatically enlists it in the ' TransactionScope as a distributed transaction. connection1.Open() ' Do work in the first connection. ' Assumes conditional logic in place where the second ' connection will only be opened as needed. Using connection2 As New OracleConnection(connectString2) ' Open the second connection, which enlists the ' second connection and promotes the transaction to ' a full distributed transaction. connection2.Open() ' Do work in the second connection. End Using End Using ' The Complete method commits the transaction. transScope.Complete() ' The result of transaction will be available at the database after ' disposing TransactionScope End Using
直接模式連接也登記在分布式事務中。但在這種情況下,將只仿真TransactionScope支持,因為在直接模式下不支持兩階段提交。將為其范圍內的每個連接創建單獨的OracleTransaction。這些OracleTransaction的工作不完全同步:
如果對某個已登記連接的操作引發異常,則可以使用try…catch塊輕松處理此情況。只需將transactionscope.complete()放在try塊的最后一行。因此,任何異常情況下的代碼執行都不會到達complete()行,分布式事務也不會被提交。另一方面,可能會發生以下情況:在兩個已登記到TransactionScope連接上的所有操作都會成功地執行,沒有例外,但如果在處理TransactionScope(當操作實際提交到數據庫時)時,第一個OracleTransaction失敗(例如,服務器故障或終止數據庫會話),則e第二個OracleTransaction仍處于提交狀態,并且TransactionScope成功完成(沒有其第一個OracleTransaction)。
一個OracleTransaction的更改在當前TransactionScope的其他OracleTransactions中不可見。例如,第70條記錄將在OCI模式下的TransactionScope中插入和更新,但僅在直接模式下插入(未更新):
using (TransactionScope ts = new TransactionScope()) { using (OracleConnection connection = new OracleConnection(connStr)) { connection.Open(); OracleCommand command = connection.CreateCommand(); command.CommandText = "insert into dept(deptno,dname,loc) values (70,'Development','London')"; command.ExecuteNonQuery(); } using (OracleConnection connection2 = new OracleConnection(connStr)){ connection2.Open(); OracleCommand command2 = connection2.CreateCommand(); command2.CommandText = "update dept set loc='New York' where deptno=70"; command2.ExecuteNonQuery(); } ts.Complete(); }
Using ts As New TransactionScope() Using connection As New OracleConnection(connStr) connection.Open() Dim Command As OracleCommand = connection.CreateCommand() Command.CommandText = "insert into dept(deptno,dname,loc) values (70,'Development','London')" Command.ExecuteNonQuery() End Using Using connection2 As New OracleConnection(connStr) connection2.Open() Dim Command2 As OracleCommand = connection2.CreateCommand() Command2.CommandText = "update dept set loc='New York' where deptno=70" command2.ExecuteNonQuery() End Using ts.Complete() End Using
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn