彩票走势图

dotConnect for Oracle入门指南(六):使用事务

翻译|使用教程|编辑:李爽夏|2019-01-22 10:48:14.000|阅读 191 次

概述:本教程说明了从.NET代码(不包含envolving PL/SQL事务)操作事务的方法。

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

【下载dotConnect for Oracle最新版本】

dotConnect for Oracle(原名OraDirect.NET)建立在ADO.NET技术上,为基于Oracle数据库的应用程序提供完整的解决方案。它为设计应用程序结构带来了新的方法,提高工作效率,使数据库应用程序的开发更简便。

使用事务

  • 了解事务
  • 本地事务
  • OCI模式下的分布式事务
  • 直接模式下的分布式事务

了解事务

事务是一个或多个被视为单个工作单元的操作,完全完成或完全无效(“全部或无”)。如果事务中某一点发生故障,则所有更新都可以回滚到其事务前状态。事务必须符合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

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命名空间。

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
购买dotConnect for Oracle正版授权的朋友可以点击""哦~~~
PyCharm

标签:数据库SQL服务器oracle

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP