2016-04-21 103 views
8

我只是一个普遍类型的问题。如果我有一个调用SQL Server存储过程的C#应用​​程序,并且C#应用程序超时,那么服务器上的过程调用是否会继续运行以完成它?如果我的C#超时存储过程调用,该过程是否继续运行?

+1

有两种不同的超时...有一个连接超时和命令超时 –

+1

真的不清楚你的C#应用​​程序“超时”的意思。存储过程不会在C#应用程序中等待任何事情。一旦SP启动,它将运行完成。但是,如果执行SP之后的某些C#代码导致应用程序冻结并最终终止,并且这发生在显式事务范围内,那么会回滚。 – AaronLS

+0

这是发生的CommandTimeout。有问题的过程不会返回任何数据,理论上不需要C#应用程序来启动过程调用以外的任何其他功能。没有交易,只是调用程序。所以你说如果CommandTimeout“超时”,程序将继续运行? – Wizaerd

回答

0

如果您使用SQlCommand类,则一旦应用程序超时,查询执行将回滚。

+2

不确定我是否同意这取决于查询是否包含在事务中 –

2

简短的回答是肯定的....这里是一些信息备份我的要求

实际上,有几个地方,一个应用程序可以“超时”,但一个是命令的执行时间了...

命令执行超时 - 此属性是命令执行或处理结果期间所有网络读取的累计超时。在返回第一行后仍然可能发生超时,并且不包括用户处理时间,仅包括网络读取时间。

如果命令超时,命令不会自行回滚。如果代码超时,这将需要代码周围的事务。

如果在返回行时发生超时,则意味着随时可能发生超时C#不会告诉SQL Server停止运行该命令。事情,可这样做在交易

源包装命令:https://blogs.msdn.microsoft.com/mattn/2008/08/29/sqlclient-timeouts-revealed/ ...和经验

+0

您链接的大部分描述是如果检索行。在我的情况下,存储过程不会返回任何结果。它开始了夜间进口工作。因此,如果C#CommandTimeout在服务器上运行该过程时超时,它是否会继续在服务器上运行,即使C#连接超时? – Wizaerd

+0

我认为描述......在第一行意味着它可以在第一行返回之前的任何时候仍然可以发生。所有超时的意思是,这是超过它应该超过时间 –

0

我的想法有关是,它是所有关于通过调用的程序打开的连接。 如果你的代码是在一个使用块内执行的,或者它是垃圾收集的,那么我认为SP的执行将会回滚。

1

不。以下是复制品。当超时发生时,正在运行的进程将被终止,立即停止。如果您没有指定事务,则超时之前在存储过程中完成的工作将会持续。同样,如果与服务器的连接被外部力量切断,SQL Server将终止正在运行的进程。

using (var conn = new SqlConnection(@"Data Source=.;Initial Catalog=Test;Integrated Security=True")) 
{ 
    conn.Open(); 

    using (var setupTable = new SqlCommand(@" 
     IF NOT EXISTS (
      SELECT * 
      FROM 
       sys.schemas s 
        INNER JOIN sys.tables t ON 
         t.[schema_id] = s.[schema_id] 
      WHERE 
       s.name = 'dbo' AND 
       T.name = 'TimeoutTest') 
     BEGIN 
      CREATE TABLE dbo.TimeoutTest 
      (
       ID int IDENTITY(1,1) PRIMARY KEY, 
       CreateDate datetime DEFAULT(getdate()) 
      ); 
     END 

     -- remove any rows from previous runs 
     TRUNCATE TABLE dbo.TimeoutTest;", conn)) 
    { 
     setupTable.ExecuteNonQuery(); 
    } 

    using (var checkProcExists = new SqlCommand(@" 
     SELECT COUNT(*) 
     FROM 
      sys.schemas s 
       INNER JOIN sys.procedures p ON 
        p.[schema_id] = s.[schema_id] 
     WHERE 
      s.name = 'dbo' AND 
      p.name = 'AddTimeoutTestRows';", conn)) 
    { 
     bool procExists = ((int)checkProcExists.ExecuteScalar()) == 1; 

     if (!procExists) 
     { 
      using (var setupProc = new SqlCommand(@" 
       CREATE PROC dbo.AddTimeoutTestRows 
       AS 
       BEGIN 

        DECLARE @stop_time datetime; 

        SET @stop_time = DATEADD(minute, 1, getdate()); 

        WHILE getdate() < @stop_time 
        BEGIN 
         INSERT INTO dbo.TimeoutTest DEFAULT VALUES; 

         -- wait 10 seconds between inserts 
         WAITFOR DELAY '0:00:10'; 
        END 

       END", conn)) 
      { 
       setupProc.ExecuteNonQuery(); 
      } 
     } 
    } 

    bool commandTimedOut = false; 

    try 
    { 
     using (var longExecution = new SqlCommand("EXEC dbo.AddTimeoutTestRows;", conn)) 
     { 
      // The time in seconds to wait for the command to execute. 
      // Explicitly setting the timeout to 30 seconds for clarity. 
      longExecution.CommandTimeout = 30; 

      longExecution.ExecuteNonQuery(); 
     } 
    } 
    catch (SqlException ex) 
    { 
     if (ex.Message.Contains("Timeout")) 
     { 
      commandTimedOut = true; 
     } 
     else 
     { 
      throw; 
     } 
    } 

    Console.WriteLine(commandTimedOut.ToString()); 

    // Wait for an extra 30 seconds to let any execution on the server add more rows. 
    Thread.Sleep(30000); 

    using (var checkTableCount = new SqlCommand(@" 
     SELECT COUNT(*) 
     FROM 
      dbo.TimeoutTest t;", conn)) 
    { 
     // Only expecting 3, but should be 6 if server continued on without us. 
     int rowCount = (int)checkTableCount.ExecuteScalar(); 

     Console.WriteLine(rowCount.ToString("#,##0")); 
    } 
} 

Console.ReadLine(); 

产生以下输出

True 
3 

即使从管理Studio运行存储过程将在一分钟时间帧中添加6行。

0
  Conn = new SqlConnection(ConnStr); 
      Conn.Open(); 
      myCommand = new SqlCommand(); 
      myCommand.CommandTimeout = 180000; 
      myCommand.Connection = Conn; 
      myCommand.CommandType = System.Data.CommandType.StoredProcedure; 
相关问题