【下载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 |