【下載dotConnect for Oracle最新版本】數據庫
dotConnect for Oracle(原名OraDirect.NET)創建在ADO.NET技術上,爲基於Oracle數據庫的應用程序提供完整的解決方案。它爲設計應用程序結構帶來了新的方法,提升工做效率,使數據庫應用程序的開發更簡便。服務器
使用事務oracle
- 瞭解事務
- 本地事務
- OCI模式下的分佈式事務
- 直接模式下的分佈式事務
瞭解事務
事務是一個或多個被視爲單個工做單元的操做,徹底完成或徹底無效(「所有或無」)。若是事務中某一點發生故障,則全部更新均可以回滾到其事務前狀態。事務必須符合ACID屬性-原子性、一致性、隔離性和持久性,以確保數據一致性。分佈式
若是一個事務涉及同一數據庫中的多個表,那麼PL/SQL中的顯式事務一般執行得更好。您能夠在SQL中使用Commit和Rollback語句分別修復和放棄當前PL/SQL塊中之前的命令。性能
不然,能夠經過設計用於Oracle數據庫的庫/程序集中的特殊命令類來實現具備普通SQL的事務。例如,您可使用devart.data.oracle.oraclecommand:在oraclecommand的鏈接上啓動事務,經過此oraclecommand執行多個SQL語句,並在必要時提交/回滾全部操做。請參閱本地事務主題中的示例。spa
本文描述了從.NET代碼(不包含envolving PL/SQL事務)操做事務的方法——這是處理事務最多見的狀況。關於您的任務,您能夠選擇要實現的事務類型-本地或分佈式。當事務是單階段事務而且由數據庫直接處理時,被認爲是本地事務的事務。分佈式事務是一個影響多個資源的事務,它由事務監視器協調,並使用故障保護機制(如兩階段提交)來解決事務。設計
注意:Oracle不支持SQL Server中使用的可升級事務,分佈式事務的實如今OCI和Direct模式下有所不一樣。還要考慮到TransactionScope(分佈式事務)僅在處理時完成。code
本地事務
dotConnect for Oracle具備用於執行本地事務的OracleTransaction對象。當一個鏈接對象上的多個操做應做爲一個事務執行時,使用OracleTransaction。應用程序經過對OracleConnection對象調用BeginTransaction來建立OracleTransaction對象。與事務相關聯的全部後續操做(例如,提交或停止事務)都在OracleTransaction對象上執行。OracleConnection和OracleTransaction之間的相關性始終爲1:1。所以,一次只能爲單獨的OracleConnection建立一個OracleTransaction。對象
例子:事務
下面的示例建立OracleConnection和OracleTransaction。它還演示瞭如何使用BeginTransaction、Commit和Rollback方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
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(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
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 |
OCI模式下的分佈式事務
若是要將對多個鏈接對象執行的操做放入同一分佈式事務中,則須要將它們登記到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命名空間。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
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 } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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中插入和更新,但僅在直接模式下插入(未更新):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
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 |