0

更新 1:以下代码在我的 DEV 机器上运行良好,但在测试/生产服务器上失败。

public TransImport()
{
ConnString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
SqlConnection conn_new;
SqlCommand command_serial_new;
SqlTransaction InsertUpdateSerialNumbers;

conn_new = new SqlConnection(ConnString);
command_serial_new = conn_new.CreateCommand();
command_serial_new.CommandText = "SELECT 1 FROM YSL00020 WITH (NOLOCK) WHERE SERLNMBR = @slnr";
var p = new SqlParameter("@slnr", SqlDbType.NVarChar, 50);
command_serial_new.Parameters.Add(p);

InsertUpdateSerialNumbers = conn.BeginTransaction();
boolean bErrors = false;
while (!headerFileReader.EndOfStream)
{
     headerRow = headerFileReader.ReadLine();

     if (!CheckSerialNumber(headerFields[0].Trim()))
        {
        bErrors = true;
        break;
        }
  }
if (bErrors)
  InsertUpdateSerialNumbers.Commit();
else
  InsertUpdateSerialNumbers.Rollback();

if (conn_new != null)
{
    conn_new.Close();
    conn_new.Dispose();
}

}

private Boolean CheckSerialNumber(string SerialNumber)
{
command_serial_new.Parameters["@slnr"].Value = SerialNumber;
try
{
    var itExists = Convert.ToInt32(command_serial_new.ExecuteScalar()) > 0;
    if (!itExists)
    {
        command_serial.Transaction = InsertUpdateSerialNumbers;
        command_serial.CommandText = "INSERT INTO YSL00([Manifest_Number],[PONUMBER],[ITEMNMBR],[SERLNMBR]"
         + "VALUES ('" + Manifest + "','" + PONr + "','" + itemNumber + "','" + serialNr  + "')";
        var insertStatus = command_serial.ExecuteNonQuery();
        return true;
    }
}
catch (Exception ex)
{
    LogException(ex, "Error in CheckSerialNumber =>"+ command_serial_new.CommandText.ToString());
}
return false;
}

我在上面的代码中遇到的问题:

我正在使用带有提交和回滚的 SQLTransaction。我遍历一个平面文件并更新一些表。文件通常包含大约 500 到 1000 行。我正在为每一行(使用 sqltransaction)创建 INSERT 语句,并且程序在 COMMIT 语句处暂停很长时间,最终我得到如下所示的错误。但是,如果我注释掉整个 sqltransaction(以及提交和回滚),一切都很好,但我们需要提交和回滚。有没有办法只创建一个事务(我现在正在为每个 INSERT 语句创建),这样我就不会收到如下错误。

System.ServiceModel.CommunicationException

从管道读取错误:管道已结束。(109, 0x6d)。mscorlib

服务器堆栈跟踪:在 System.ServiceModel.Channels.SessionConnectionReader.Receive(TimeSpan 超时)在 System.ServiceModel.Channels 的 System.ServiceModel.Channels.StreamConnection.Read(Byte[] 缓冲区,Int32 偏移量,Int32 大小,TimeSpan 超时)。 SynchronizedMessageSource.Receive(TimeSpan timeout) at System.ServiceModel.Channels.FramingDuplexSessionChannel.Receive(TimeSpan timeout) at System.ServiceModel.Channels.FramingDuplexSessionChannel.TryReceive(TimeSpan timeout, Message& message) at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message消息,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串操作,布尔单向,ProxyOperationRuntime 操作,Object[] 输入,Object[] 输出,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(String行动,Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs) at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

在 [0] 处重新引发异常:在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 类型) 处的 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)

4

2 回答 2

1

有几件事将有助于改善这一点。

SqlConnection首先将命令包装在using.

第二个听起来像 prod 需要更长的时间来运行它,这就是它超时的原因。您可以将超时设置为无限制。

最后,如果您使用的是 SQL Server 2008+,您应该使用批量插入。

Insert into table (column1, column2) values (value1, value2), (value3, value4)

另一个注意事项是,在动态构建这些时,一次控制一千个值的限制。

于 2013-10-09T23:58:46.667 回答
0

用批量插入修改了我的代码,没有问题。

于 2013-10-11T16:18:34.667 回答