我正在使用SqlConnection类并遇到命令超时到期的问题。
首先,我使用SqlCommand属性来设置命令超时,如下所示:
example@gmail.com
此外,我已确保将Execution Timeout设置设置为0,以确保SQL管理方面不会有超时。
这是我的代码:
command.CommandTimeout = 300;
我已经设置了日志记录并且可以在启动此功能后正好验证30秒,我在堆栈跟踪中收到以下错误消息:
using (SqlConnection conn = new SqlConnection(connection))
{
conn.Open();
SqlCommand command = conn.CreateCommand();
var transaction = conn.BeginTransaction("CourseLookupTransaction");
command.Connection = conn;
command.Transaction = transaction;
command.CommandTimeout = 300;
try
{
command.CommandText = "TRUNCATE TABLE courses";
command.ExecuteNonQuery();
List<Course> courses = CourseHelper.GetAllCourses();
foreach (Course course in courses)
{
CourseHelper.InsertCourseLookupRecord(course);
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
Log.Error(string.Format("Unable to reload course lookup table: {0}", ex.Message));
}
}
为了完全披露: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
在上述InsertCourseLookupRecord()
语句中找到,正在对同一数据库中的同一个表执行另一个查询。以下是它正在执行的查询:
using
此表中有超过1400条记录。
我会证明任何帮助我解决这个问题的人都是最高级的伟大巫师。
答案 0 :(得分:4)
我相信发生的事情是您遇到了导致InsertCourseLookupRecord()
函数中的查询失败的死锁情况。您没有将连接传递给InsertCourseLookupRecord()
,所以我假设您在单独的连接中运行它。那么会发生什么:
您可以更改函数以接受命令对象作为参数,并在函数内部使用它而不是创建新连接。这将成为交易的一部分,并将全部共同承诺。
要执行此操作,请将功能定义更改为:
public static int InsertCourseLookupRecord(string course, SqlCommand cmd)
从函数中取出所有连接代码,因为您将使用cmd对象。然后,当您准备好执行查询时:
myCommand.Parameters.Clear(); //need only if you're using command parameters
cmd.CommandText = "INSERT BLAH BLAH BLAH";
cmd.ExecuteNonQuery();
它将在相同的连接和事务上下文中运行。
您在使用区块中将其称为:
CourseHelper.InsertCourseLookupRecord(course, command);
您也可以只使用InsertCourseLookupRecord中的代码并将其放在for循环中,然后在using块中重用命令对象,而无需将其传递给函数。
答案 1 :(得分:1)
因为您使用了两个单独的SqlConnection
个对象,所以由于您在外部代码中启动SqlTransaction
而导致自我陷入僵局。 InsertCourseLookupReacord
中的查询以及GetAllCourses
中的查询可能会被尚未提交的TRUNCATE TABLE courses
调用阻止。他们等待300秒,然后提交截断,然后超时。
您有几个选择。
SqlTransaction
传递给GetAllCourses
和InsertCourseLookupRecord
,以便它们可以成为同一交易的一部分。SqlTransaction
并使用System.Transaction.TransactionScope
来使用“环境交易”。这会导致打开到服务器的所有连接都共享一个事务。这可能会导致维护问题,具体取决于查询正在执行的操作,因为它可能需要调用可能在某些计算机上禁用的Distributed Transaction Coordinator(从您显示的内容看起来需要DTC,因为您有两个同时打开连接。)。最好的选择是尝试更改代码以执行选项1,但如果您不能执行选项2.
答案 2 :(得分:0)
对上下文连接执行命令时,CommandTimeout无效(在连接字符串中使用“context connection = true”打开SqlConnection)
请检查您的连接字符串,这是我能想到的唯一可能性。