Oracle.ManagedDataAccess.Client与System.Data.OracleClient的OracleTransaction

在没有使用EF的情况下,访问Oracle数据库可以引用微软提供的System.Data.OracleClient或者Oracle提供的Oracle.ManagedDataAccess.Client。因此对于OracleTransaction的使用方法也会有不同,需要注意的是,尽量使用Oracle.ManagedDataAccess.Client,因为微软在未来的版本不会再支持System.Data.OracleClient。

微软文档:https://docs.microsoft.com/en-us/dotnet/api/system.data.oracleclient.oracletransaction?view=netframework-4.8

Oracle文档:https://docs.oracle.com/database/121/ODPNT/OracleTransactionClass.htm#ODPNT2214


如果在数据插入分成多个部分,任何一部分的失败整个流程的数据都不应该插入到数据库,或者插入数据的步骤包括了代码的操作和存储过程的操作,这时就需要使用Transaction。

主要使用:BeginTransaction,Commit和Rollback

System.Data.OracleClient下的OracleTransaction

需要对command的Transaction进行赋值

public void RunOracleTransaction(string connectionString)
{
    using (OracleConnection connection = new OracleConnection(connectionString))
    {
        connection.Open();

        OracleCommand command = connection.CreateCommand();
        OracleTransaction transaction;

        // Start a local transaction
        transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted);
        // Assign transaction object for a pending local transaction
        command.Transaction = transaction;

        try
        {
            command.CommandText =
                "INSERT INTO Dept (DeptNo, Dname, Loc) values (50, 'TECHNOLOGY', 'DENVER')";
            command.ExecuteNonQuery();
            command.CommandText =
                "INSERT INTO Dept (DeptNo, Dname, Loc) values (60, 'ENGINEERING', 'KANSAS CITY')";
            command.ExecuteNonQuery();
            transaction.Commit();
            Console.WriteLine("Both records are written to database.");
        }
        catch (Exception e)
        {
            transaction.Rollback();
            Console.WriteLine(e.ToString());
            Console.WriteLine("Neither record was written to database.");
        }
    }
}

Oracle.ManagedDataAccess.Client下的OracleTransaction

不需要对command的Transaction进行赋值,默认使用当前Connection中的Transaction.

using Oracle.ManagedDataAccess.Client;
class OracleTransactionSample
{
  static void Main()
  {
   
    string constr = "User Id=scott;Password=tiger;Data Source=oracle";
    OracleConnection con = new OracleConnection(constr);
    con.Open();
 
    OracleCommand cmd = con.CreateCommand();
 
    // Check the number of rows in MyTable before transaction
    cmd.CommandText = "SELECT COUNT(*) FROM MyTable";    
    int myTableCount = int.Parse(cmd.ExecuteScalar().ToString());
 
    // Print the number of rows in MyTable
    Console.WriteLine("myTableCount = " + myTableCount);
 
    // Start a transaction
    OracleTransaction txn = con.BeginTransaction(
      IsolationLevel.ReadCommitted);
 
    try
    {
      // Insert the same row twice into MyTable
      cmd.CommandText = "INSERT INTO MyTable VALUES (1)";
      cmd.ExecuteNonQuery();
      cmd.ExecuteNonQuery(); // This may throw an exception
      txn.Commit();
    }
    catch (Exception e)
    {
      // Print the exception message
      Console.WriteLine("e.Message    =  " + e.Message);
 
      // Rollback the transaction
      txn.Rollback();
    }    
 
    // Check the number of rows in MyTable after transaction    
    cmd.CommandText = "SELECT COUNT(*) FROM MyTable";
    myTableCount = int.Parse(cmd.ExecuteScalar().ToString());
 
    // Prints the number of rows
    // If MyColumn is not a PRIMARY KEY, the value should increase by two.
    // If MyColumn is a PRIMARY KEY, the value should remain same.
    Console.WriteLine("myTableCount = " + myTableCount);
 
    txn.Dispose();
    cmd.Dispose();
 
    con.Close();
    con.Dispose();
  }
}

关于在代码中使用存储过程

如果在事务中包含了对存储过程的操作,那么在存储过程中不要使用commit,否则会导致所有数据的更新。如果一定在存储过程中使用commit,则应该使用自主事务:AUTONOMOUS_TRANSACTION

当调用自主事务时,主事务被挂起。 自主事务完全独立于主事务:它们不共享锁,资源或提交依赖项。 自主交易不影响主交易。

自主事务提交时,自主事务所做的更改对其他事务可见。 仅当主事务的隔离级别为READ COMMITTED(缺省)时,它们才对主事务恢复可见。

使用方法

CREATE PROCEDURE lower_salary (emp_id NUMBER, amount NUMBER) AS
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  UPDATE employees SET salary =
    salary - amount WHERE employee_id = emp_id;
  COMMIT;
END lower_salary;

详细介绍参考Oracle官方文档:https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/autotransaction_pragma.htm#LNPLS01302

你可能感兴趣的:(基本概念,oracle)