在同一表上获取 SqlTransaction 的超时错误
本文关键字:SqlTransaction 超时 错误 获取 | 更新日期: 2023-09-27 18:34:50
public TransImport()
{
ConnString = ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
SqlConnection conn_new;
SqlCommand command_serial_new;
SqlConnection conn;
SqlCommand command_serial;
SqlTransaction InsertUpdateSerialNumbers;
conn = new SqlConnection(ConnString);
command_serial = conn.CreateCommand();
conn_new = new SqlConnection(ConnString);
command_serial_new = conn_new.CreateCommand();
command_serial_new.CommandText = "SELECT 1 FROM YSL00 WHERE SERLNMBR = @slnr";
var p = new SqlParameter("@slnr", SqlDbType.NVarChar, 50);
command_serial_new.Parameters.Add(p);
//Here you will start reading flat file to get serialnumber.
InsertUpdateSerialNumbers = conn.BeginTransaction();
while (!headerFileReader.EndOfStream)
{
headerRow = headerFileReader.ReadLine();
if (CheckSerialNumber(headerFields[0].Trim()))
DisplayMessage("Good serialnumber"); //this function is not copied here.
}
InsertUpdateSerialNumbers.Commit();
}
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;
}
我收到错误"超时已过期。在操作或服务器完成之前经过的超时期限没有响应"。
CheckSerialNumber 函数还插入到 YSL00(我执行标量的同一个表。请参阅上面的代码(。正如我之前提到的,我读取和更新 YSL000 表的平面文件中有 1000 行。
请注意,我有两个单独的 sqlcommand 和两个单独的连接来处理这个问题。原因是使用 sqltransaction 它不允许我在同一个表上进行查询。我认为超时可能因此而发生?
感谢您的阅读。请建议
更新1:由于我没有粘贴整个代码,我想提一下,在程序中使用以下代码完成处置。
if (conn != null)
{
conn.Close();
conn.Dispose();
}
if (conn_new != null)
{
conn_new.Close();
conn_new.Dispose();
}
您可以增加 SqlConnection 对象的时间。
您可以使用 ConnString 执行此操作:
string connStr = "Data Source=(local);Initial Catalog=AdventureWorks;Integrated
Security=SSPI;Connection Timeout=300";
我认为默认隔离级别 - 读取提交 - 正在阻止您的"检查序列号"方法有效。Command_serial_new不会考虑循环中插入的行 - 这可能会导致一些麻烦。老实说,我也会寻找一些僵局。也许command_serial_new实际上被其他事务完全阻止了。
首先:
- 将查询command_serial_new设置为:
SELECT 1 FROM YSL00 WITH (NOLOCK) WHERE SERLNMBR = @slnr
- 考虑使用较低的隔离级别来查询插入的行(将其设置为读取未提交(。
- 关闭您的连接和交易。
- 只使用一个 SqlConnection - 你不需要其中的两个。
您正在使用的许多对象都实现了 IDisposable,您应该使用 using 语句包装它们。如果没有这些 using 语句,.NET 不一定会在垃圾回收器运行不确定的时间之前删除对象,并且如果它仍在某处保持事务打开状态,则可能会阻止后续查询。
例如,您需要使用 using 语句包装连接:
using (conn_new = new SqlConnection(ConnString)) {
...
如果我
没记错的话,您需要将文件内容与表内容合并。为此,我会推荐你
- 将文件内容复制到临时表中(请参阅临时表和大容量插入(
- 使用命令 MERGE (http://msdn.microsoft.com/en-us/library/bb510625.aspx( 将临时表内容与原始表合并