2017-04-19 42 views
0

我有一个.exe项目与4个线程。每个线程调用Windows服务中托管的WCF服务并插入一条记录(从1到5,000条记录循环)。测试项目将尝试将20000条记录插入到WCF服务中。 WCF服务中的服务行为是每个会话。C#SqlCommand插入多个记录时返回输入参数

我使用存储过程将记录插入到SQL Server 2008R2 Express中。我遇到的问题是SqlCommand。当只有一个线程正在运行时,不会发生错误,但是当两个或更多线程正在运行时,代码将引发错误,但不确定错误类型。

如果您看下面的代码,从.ExecuteReader读取结果时发生错误(这是一个强制异常错误)。它不会返回我在存储过程中定义的错误(我猜它永远不会到数据库),它会返回一个包含txn记录所有参数的XML,但它不会仅返回当前事务,它也会从在另一个线程上运行的事务返回记录。如果我直接在SQL Server Management Studio中执行存储过程,它可以正常工作,所以我放弃了数据库端的任何隔离级别问题。

正如你所看到的方法不是静态的,SqlCommand创建和处置每个电话,所以我真的很担心这一点。有任何想法吗?

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和错误描述的表,我在这里检索:results [“Value_log”]。ToString();在使用2个线程运行400条记录之后,而不是返回该数据表,返回带有SP插入参数及其值的完全不同的XML数据集:Tipo,Cajero,TermId等。奇怪的是,不仅返回当前事务,之前插入的400个事务。所以,错误是CastException,在程序从SP Datatable返回的结果中找不到Value_log。 –

回答

1

您正在执行DML操作,你的情况INSERT(从您发布的代码new SqlCommand("InsertInvoice", con)),那么为什么ExecuteReader()它,而应该是cmd.ExecuteNonQuery()

+0

“InsertInvoice”是SQL存储过程的名称,使用ExecuteReader的原因是因为SP返回一个DataTable,其中包含我在此方法中返回的信息: InsertInvoiceRow row = returnData.NewInsertInvoiceRow(); 尝试 { row.TIPO_log = results [“Type_log”]。ToString(); row.VALOR_LOG = results [“Value_log”]。ToString(); } –