【问题标题】:Does a stored procedure finish on "Execution Timeout Expired" (VB.Net)?存储过程是否在“执行超时已过期”(VB.Net)上完成?
【发布时间】:2018-11-06 07:42:52
【问题描述】:

所以我在 VB.Net 中有一个正常的System.Data.IDbCommand 执行存储过程。三十秒后(System.Data.IDbCommand 默认超时)应用程序运行到“执行超时已过期”异常。到目前为止,对我来说一切都很好。

在存储过程的开始和最后是对日志表的插入。对日志表的两个条目都进行了,这让我相信存储过程,即使在超时之后仍然完成。

我找到了一个相关的帖子,但那里的答案对我来说不是很清楚: Stored Procedure and Timeout

根据this post,sql本身没有超时: Handling Timeouts inside stored procedures

即使我在 VB .Net 中收到超时,存储过程是否会在服务器上完成?存储过程(也没有在 VB.Net 中)中没有定义事务,并且 try-catch 不会引发任何错误(可能是因为 sql-server 本身没有超时 - 只是 VB.Net 连接/命令)。

这是一个存储过程的示例:

ALTER PROCEDURE [dbo].[sp_Whatever] AS BEGIN
    --Does get logged
    INSERT INTO [dbo].[T_Log](Message)
    SELECT 'Started'

    BEGIN TRY
        SET NOCOUNT ON;

        --To provoke a Timeout
        WAITFOR DELAY '00:01'
    END TRY
    BEGIN CATCH
        --Does not get logged (=no error here)
        INSERT INTO [dbo].[T_Log](Message)
        SELECT 'Error'
    END CATCH;

    --Does get logged
    INSERT INTO [dbo].[T_Log](Message)
    SELECT 'Finished'
END;

最后,在我的日志表中,我有两个条目“已开始”和“已完成”。

【问题讨论】:

  • 有时,您必须回答真正的问题。不要依赖未来可能改变的行为。让您的代码正常运行。
  • SqlClient 在执行超时时向 SQL Server 发送取消信号。有时 SQL Server 会接受取消信号,但有时却不能。请参阅这篇博文:blog.sqlworkshops.com/… 和另一篇:blogs.msdn.microsoft.com/khen1234/2005/10/20/…
  • 想知道为什么 System.Data.IDbCommand 而不是 System.Data.SQLClient Command 类。一定是我头顶的一些工厂模式。

标签: sql-server vb.net


【解决方案1】:

一旦发送到服务器,您的存储过程将一直执行直到完成,除非被取消。

如果您的客户端应用遇到命令超时,它会通知 SQL Server 取消操作。

应该回滚任何更改,但我实际上并不想在不检查的情况下依赖此行为,因为实际发生的情况取决于其他一些设置,例如 XACT_ABORT

这里有一个非常详细的解释。

https://blogs.msdn.microsoft.com/khen1234/2005/10/20/theres-no-such-thing-as-a-query-timeout/

需要注意的是,当客户端超时时停止命令实际上是客户端发送的另一个命令。它严格来说是一个客户端构造,与服务器上发生的任何事情无关。服务器上没有任何实际超时。

如果一切正常,客户端超时应该停止命令,并且根据配置和命令,更改应该回滚。

但是,如果在客户端发送取消命令(电源故障、不礼貌的重启等)之前发生了实际断开客户端连接的错误事件,则执行将继续直到完成。

【讨论】:

    猜你喜欢
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 1970-01-01
    • 2021-12-03
    相关资源
    最近更新 更多