我只是一般的问题。如果我有一个调用SQL Server存储过程的C#应用程序,并且C#应用程序超时,那么服务器上的过程调用是否继续运行到它的完成?
答案 0 :(得分:2)
简短回答是......这里有一些信息可以支持我的索赔
实际上有几个地方应用程序可以'超时',但其中一个是命令执行超时......
命令执行超时 - 此属性是命令执行或处理结果期间所有网络读取的累计超时。返回第一行后仍可能发生超时,并且不包括用户处理时间,仅包括网络读取时间。
如果命令超时,它将不会自行回滚。如果超时,这将需要围绕代码进行交易。
如果在返回行时发生超时,则意味着任何时候都可能发生超时C#不会告诉SQL Server停止运行该命令。可以采取相关措施,例如在事务中包装命令
来源:https://blogs.msdn.microsoft.com/mattn/2008/08/29/sqlclient-timeouts-revealed/ ...和经验
答案 1 :(得分: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
即使从Management Studio运行存储过程,也会在一分钟的时间范围内添加6行。
答案 2 :(得分:0)
如果您正在使用SQlCommand类,则一旦应用超时,将回滚查询执行。
答案 3 :(得分:0)
我对此的想法是关于通过调用程序打开的连接的全部内容。 如果您的代码在使用块中执行或者它是垃圾收集,那么我认为SP的执行将被回滚。
答案 4 :(得分:0)
Conn = new SqlConnection(ConnStr);
Conn.Open();
myCommand = new SqlCommand();
myCommand.CommandTimeout = 180000;
myCommand.Connection = Conn;
myCommand.CommandType = System.Data.CommandType.StoredProcedure;