2017-01-20 134 views
1

私は2つのテーブルTable1、Table2を持っています。最初は、table1に1行を挿入し、挿入された行のIDを取得する必要があります。このIDをtable2に使用します。しかし、table2にデータを挿入中にエラーが発生した場合は、table1もロールバックする必要があります。私はステートメントを使用して書いていますが、まだこれは起こっていません。これは私がデータベースにコミットされているデータをロールバックする方法

using(cn = new SqlConnection(connectionString)) 
     { 
     cn.open() 
      using (var cm = cn.CreateCommand()) 
       { 
        cm.CommandType = CommandType.StoredProcedure; 
        cm.CommandText = Constants.InsertNewJob; // inserts a job in table1 
        try 
        { 
         var jobId = Convert.ToInt32(cm.ExecuteScalar()); 

         DataTable dt = QueueData.ToDataTable(); // queuedata contains large data which is converted to datatable 
         dt.Columns.Add("JobId", typeof(int), jobId.ToString()); // adding the retrieved jobId to datatable 

         using (SqlBulkCopy bulkCopy = new SqlBulkCopy(cn)) 
          { 
           bulkCopy.DestinationTableName = Constants.DestinationTableName; //Table 2 which uses job id which is retrieved from Table 1 
           bulkCopy.ColumnMappings.Add("JobId", "JobId"); 
           bulkCopy.ColumnMappings.Add("DateTime", "DateTime"); 
           bulkCopy.WriteToServer(dt); 
          } 
         } 
         catch(Exception ex) 
         { 
          Logger.Error(ex.Message, "Error while inserting data"); 
         } 
        } 
        catch (Exception ex) 
        { 
         Logger.Error(ex.Message, "Error while inserting new job into transaction table"); 
        } 
       } 
       cn.close() 
     } 

はまだTABLE1に追加されたデータを一括挿入する表に誤りがある場合に裏打ちされたロールを取得していないしようとしたものです。親切に助けてください。 ありがとう

+2

こちらのキーワードは取引です。 https://msdn.microsoft.com/en-us/library/2k2hy99x(v=vs.110).aspxを参照してください。 'using'文はエラー時に魔法のように物事をロールバックしません。 –

答えて

2

transactionをSqlBulkCopyコンストラクタに渡す必要があります。

using (SqlTransaction transaction = myConnection.BeginTransaction()) 
{ 
    using (var bulkCopy = new SqlBulkCopy(myConnection, SqlBulkCopyOptions.Default, transaction)) 
    { 
     try 
     { 
      bulkCopy.DestinationTableName = Constants.DestinationTableName; 
      bulkCopy.ColumnMappings.Add("JobId", "JobId"); 
      bulkCopy.ColumnMappings.Add("DateTime", "DateTime"); 
      bulkCopy.WriteToServer(dataSource); 
      transaction.Commit(); 
     } 
     catch (Exception ex) 
     { 
      Logger.Error(ex.Message, "Error while inserting data"); 
      transaction.Rollback(); 
     } 
    } 
} 

this articleを参照してください。

+0

:)その作業に感謝します。まさに私が望んでいたもの。 –

0

トランザクションを作成する必要があります。 MSDN websiteをご覧ください。

簡単な例:

// Start a local transaction. 
    transaction = cn.BeginTransaction("SampleTransaction"); 

    // Must assign both transaction object and connection 
    // to Command object for a pending local transaction 
    command.Connection = cn; 
    command.Transaction = transaction; 

    // TRY to query the database 
    // transaction.Commit(); 

その後、あなたのcatchブロックtransaction.Rollback();を使用しています。

+0

:正確に処理するためには、トランザクションを 'using'ステートメントでラップしてください。売却された場合、トランザクションは前もってコミットされていない場合はロールバックされます –

関連する問題