2012-08-16 78 views
0

我已經在C#中編寫了一個類,旨在提供在給定的數據庫連接上運行數據庫事務的能力。當我嘗試運行代碼時,我分別在Oracle和SQL Server上收到以下兩個錯誤。看看我的代碼是否有一個簡單的方法呢?C#通過ADO.NET失敗的Oracle和SQL Server事務

甲骨文

連接已經是一個地方的部分或分佈式事務

SQL Server 2008的

的SqlConnection不支持並行ŧ ransactions

基類

public abstract class DbFactoryDatabaseTransaction 
    { 
    public void DoTransaction(IDatabaseConnectivityObjectBasicResponse databaseConnectivityObject) 
    { 
     databaseConnectivityObject.PrepareConnection(); 

     DbTransaction dbTransaction = databaseConnectivityObject.DBFactoryDatabaseConnection.BeginTransaction(); 

     try 
     { 
      ExecuteSql(databaseConnectivityObject, dbTransaction); 

      dbTransaction.Commit(); 
     } 
     catch (Exception ex) 
     { 
      dbTransaction.Rollback(); 

      databaseConnectivityObject.Close(); 

      throw; 
     } 
     finally 
     { 
      dbTransaction.Dispose(); 
     } 
    } 


    /// <summary> 
    /// A method to allow the caller to decide how the SQL statements are called as part of a transaction 
    /// </summary> 
    public abstract void ExecuteSql(IDatabaseConnectivityObjectBasicResponse databaseConnectivityObject, DbTransaction dbTransaction); 
} 

覆蓋方法

public override void ExecuteSql(IDatabaseConnectivityObjectBasicResponse databaseConnectivityObject, DbTransaction dbTransaction) 
    { 
     //oracle 
     List<string> transactions = new List<string> 
      { 
       "INSERT INTO TMA_NOT_TO_ENTITY_QUEUE (RECEIVED_NOTICE_ID, NOTICE_TEXT, STATE_ID, TIME_RECEIVED) VALUES (1, 'This is a notice', 1, to_date('2012/08/15', 'yyyy/mm/dd'))", 
       "INSERT INTO TMA_NOT_TO_ENTITY_QUEUE (RECEIVED_NOTICE_ID, NOTICE_TEXT, STATE_ID, TIME_RECEIVED) VALUES (2, 'This is a notice', 1, to_date('2012/08/15', 'yyyy/mm/dd'))", 
       "INSERT INTO TMA_NOT_TO_ENTITY_QUEUE (RECEIVED_NOTICE_ID, NOTICE_TEXT, STATE_ID, TIME_RECEIVED) VALUES (3, 'This is a notice', 1, to_date('2012/08/15', 'yyyy/mm/dd'))", 
       "INSERT INTO TMA_NOT_TO_ENTITY_QUEUE (RECEIVED_NOTICE_ID, NOTICE_TEXT, STATE_ID, TIME_RECEIVED) VALUES (4, 'This is a notice', 1, to_date('2012/08/15', 'yyyy/mm/dd'))", 
       "INSERT INTO TMA_NOT_TO_ENTITY_QUEUE (RECEIVED_NOTICE_ID, NOTICE_TEXT, STATE_ID, TIME_RECEIVED) VALUES (5, 'This is a notice', 1, to_date('2012/08/15', 'yyyy/mm/dd'))", 
       "INSERT INTO TMA_NOT_TO_ENTITY_QUEUE (RECEIVED_NOTICE_ID, NOTICE_TEXT, STATE_ID, TIME_RECEIVED) VALUES (6, 'This is a notice', 1, to_date('2012/08/15', 'yyyy/mm/dd'))" 
      }; 

     databaseConnectivityObject.DBFactoryDatabaseCommand.Transaction = databaseConnectivityObject.DBFactoryDatabaseConnection.BeginTransaction(); 

     foreach (var transaction in transactions) 
     { 
      databaseConnectivityObject.DBFactoryDatabaseCommand.CommandText = transaction; 
      databaseConnectivityObject.DBFactoryDatabaseCommand.CommandType = CommandType.Text; 
      databaseConnectivityObject.DBFactoryDatabaseCommand.Transaction = dbTransaction; 
      databaseConnectivityObject.DBFactoryDatabaseCommand.ExecuteNonQuery(); 
     } 
    } 

調用方法

public void RunTransaction() 
     { 
     IDatabaseConnectivityObjectBasicResponse databaseConnectivityObject = new DbProviderFactoryConnectionBasic(); 

     DoTransaction(databaseConnectivityObject); 
     } 

的測試方法

[TestMethod()] 
    public void RunTransactionTest() 
    { 
     TmaNoticeToClusteredEntityValidation target = new TmaNoticeToClusteredEntityValidation(BindVariables, SqlFactory, Dialect); 
     target.RunTransaction(); 
     Assert.Inconclusive("A method that does not return a value cannot be verified."); 
    } 

回答

2

事實證明,這個問題實際上是,我是連接對象上調用的BeginTransaction兩次()。這是通過從覆蓋方法中刪除databaseConnectivityObject.DBFactoryDatabaseCommand.Transaction = databaseConnectivityObject.DBFactoryDatabaseConnection.BeginTransaction(); 來解決的。

0

只是省略上覆蓋

databaseConnectivityObject.DBFactoryDatabaseCommand.Transaction = databaseConnectivityObject.DBFactoryDatabaseConnection.BeginTransaction(); 

此行並更改該

databaseConnectivityObject.DBFactoryDatabaseCommand.Transaction = dbTransaction; 

databaseConnectivityObject.DBFactoryDatabaseCommand.Connection= databaseConnectivityObject.DBFactoryDatabaseConnection;