2017-04-19 10 views
0

私は4つのスレッドと.exeプロジェクトを持っています。各スレッドは、WindowsサービスでホストされているWCFサービスを呼び出し、レコードを挿入します(1〜5,000レコードのループ)。テストプロジェクトは、20,000レコードをWCFサービスに挿入しようとします。 WCFサービスのサービス動作はセッションごとに行われます。C#のSqlCommand戻る入力パラメータ

私は、SQL Serverの2008R2 Expressにレコードを挿入するストアドプロシージャを使用します。私が持っている問題は、SqlCommandです。スレッドが1つしか実行されていない場合はエラーは発生しませんが、2つ以上のスレッドが実行されている場合、コードはエラーをスローしますが、エラーの種類は不明です。

以下のコードを見ると、キャスト例外エラーの.ExecuteReaderから結果を読み取るときにエラーが発生します。ストアドプロシージャで定義したエラーは返されません(データベースにアクセスすることはないと推測しています)、txnレコードのすべてのパラメータを含むXMLを返しますが、現在のトランザクションのみを返します。それはまた、別のスレッドで実行中のトランザクションからレコードを返します。ストアドプロシージャをSQL Server Management Studioで直接実行すると正常に動作するため、データベース側で分離レベルの問題は破棄されます。

このメソッドが静的ではないことがわかるように、SqlCommandが作成され、呼び出されるたびに破棄されるため、私は本当にこれを心配しています。何か案は?あなたはINSERT(あなたの投稿コードnew SqlCommand("InsertInvoice", con)から)あなたのケースでは、DML操作を実行している

private InsertInvoiceDataTable SaveTransaction(Transaction Trans, ClientInfo InfoCliente) 
    { 
     InsertInvoiceDataTable returnData = new InsertInvoiceDataTable(); 

     try 
     { 
      using (SqlConnection con = new SqlConnection(ConnStr1) 
      { 

       using (SqlCommand cmd = new SqlCommand("InsertInvoice", con)) 
       { 
        cmd.CommandType = CommandType.StoredProcedure; 

        cmd.Parameters.Add("@TIPO", SqlDbType.Int).Value = Trans.InvoiceType; 
        cmd.Parameters.Add("@CAJERO", SqlDbType.VarChar).Value = Trans.Cashier; 
        cmd.Parameters.Add("@TERMID", SqlDbType.Int).Value = Trans.Term; 
        cmd.Parameters.Add("@DOB", SqlDbType.DateTime).Value = Trans.DOB; 
        cmd.Parameters.Add("@CLIID", SqlDbType.VarChar).Value = InfoCliente.ClientId; 
        cmd.Parameters.Add("@VENTANETA", SqlDbType.Decimal).Value = Convert.ToDecimal(Trans.SubTotal); 
        cmd.Parameters.Add("@IMPUESTO", SqlDbType.Decimal).Value = Convert.ToDecimal(Trans.TaxTotal); 
        cmd.Parameters.Add("@VENTATOTAL", SqlDbType.Decimal).Value = Convert.ToDecimal(Trans.Total);      

        con.Open(); 

        using (SqlDataReader results = cmd.ExecuteReader()) 
        { 
         while (results.Read()) 
          { 
           InsertInvoiceRow row = returnData.NewInsertInvoiceRow(); 
           try 
           { 
            row.TIPO_log = results["Type_log"].ToString(); 
            row.VALOR_LOG = results["Value_log"].ToString(); 

           } 
           catch (Exception ex) 
           { 
            returnData.AddInsertInvoiceRow("ERROR", ex.Message); 
            break; 
           } 
           returnData.AddInsertInvoiceRow(row); 
          } 
         } 

        con.Close(); 
        cmd.Dispose(); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Log.Error(ex); 
      returnData.AddInsertInvoiceRow("ERROR", ex.Message); 
     } 

     return returnData; 
    } 
+0

すべきですか?また、ストアドプロシージャコード。さもなければ私達は推測のままになり、それは何でもよい。 –

+0

SPにエラーがある場合、ここで取得するIdとerrorの説明を持つテーブルが返されます。results ["Value_log"]。ToString(); 2つのスレッドで実行されている400個のレコードの後に​​、そのDataTableを返す代わりに、SP挿入パラメータとその値を持つ完全な異なるXMLデータセットを返す:Tipo、Cajero、TermIdなど奇妙なことは、以前に挿入された400個のトランザクション。したがって、エラーはCastExceptionであり、プログラムがSP Datatableから期待している戻り値でValue_logを見つけることができません。 –

答えて

1

なぜExecuteReader()は、それはむしろ、おそらくあなたは、実際のエラーメッセージを共有することができcmd.ExecuteNonQuery()

+0

"InsertInvoice"はSQLストアドプロシージャの名前で、ExecuteReaderを使用する理由は、SPがメソッドで返すインフォメーション付きのDataTableを返すためです。 InsertInvoiceRow row = returnData.NewInsertInvoiceRow(); try { row.TIPO_log = results ["Type_log"]。ToString(); row.VALOR_LOG = results ["Value_log"]。ToString(); } –

関連する問題