【问题标题】:Scheduled Task SQL timeout, but not when running manually计划任务 SQL 超时,但手动运行时不会
【发布时间】:2023-03-08 19:10:01
【问题描述】:

我遇到了一个问题,我必须通过计划任务运行 C# 控制台应用程序。计划任务调用一个 Powershell 脚本,该脚本设置一些变量(如连接字符串)并调用一个 C# 控制台应用程序,该应用程序使用这些参数连接到数据库。

问题是,当计划任务由时间触发器触发时,我从日志中看到应用程序正常启动,尝试执行查询,但由于 SQl 超时而失败。

从计划任务窗口手动运行应用程序(右键单击>运行)可以正常运行,即使在自动运行失败后几秒钟也是如此。这种行为是如此一致(触发失败,手动运行),我不认为它是数据库。

这也不是启动目录、用户权限或参数差异,应用程序正在启动,只是在数据库访问失败。

此行为的原因可能是什么?我该如何补救?

任务的一些设置:

  • 以最高权限运行:开启
  • 无论用户是否登录都运行
  • 不存储密码:关闭
  • 用户帐号与登录用户相同
  • 长时间运行时触发器未停止
  • 启动目录和脚本位置正确(应用程序正在启动和记录,只是在数据库访问失败。手动右键单击>运行始终有效)

错误的堆栈跟踪:

System.Data.SqlClient.SqlException (0x80131904): Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TrySetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader

感谢您的帮助!

【问题讨论】:

  • 你的连接字符串是什么样的?考虑使用服务器的 IP 地址进行测试(如果您还没有这样做的话)。
  • 我们使用的是 CNAME 记录,所以不是连接字符串中的实际 IP。我可以正常 ping 输入连接字符串中的服务器名称,并且它正常响应。连接字符串如下所示: Server=DBSERVER-NAME;database=databaseName;uid=username;pwd=password;PersistSecurityInfo=True;但它是(应该是?)使用手动运行的相同连接字符串作为触发,那么这会产生什么影响?但接下来我会尝试实际的 IP 地址
  • 你的代码是什么样的? PowerShell 有一个 SQL 模块 (powershellgallery.com/packages/SqlServer) - 命令 Invoke-SqlCmd 有一个参数 QueryTimeout
  • @GuentherSchmitz,谢谢,我知道。我已经拥有的应用程序,它不仅仅是查询数据库或执行一些 SQL。 Powershell 仅用作使用正确参数启动应用程序的驱动程序(其中一个参数是 Powershell 计算并提供给控制台应用程序的灵活日期)

标签: sql powershell scheduled-tasks


【解决方案1】:

我确定我记得在尝试获取表 META 数据时发生了同样的超时问题。

我在这里很可能错了,但如果我没记错的话,这是由于尝试解析错误(或意外格式)的日期而导致列类型检测失败。我有一个模糊的回忆,这与操作系统区域设置、当前用户区域设置和 SQL Server 语言设置之间的不匹配有关。

您的查询是否应该返回任何日期字段?

我认为这可以通过确保在连接数据库后立即执行以下查询来强制数据库连接使用 ISO 格式的日期来解决:

        using (SqlCommand sql = new SqlCommand("SET DATEFORMAT YMD", _conn))
        {
            sql.ExecuteNonQuery();
        }

当您以交互方式运行任务时,它将连接到数据库并且格式将在您的活动区域设置中,但是当通过计划任务自动运行时,它仅模拟您的用户但不携带相关的区域设置,而是使用操作系统的设置。

【讨论】:

  • 这看起来很有可能,并且可以解释手动/自动任务的区别。实际上,应用程序查询数据库并返回日期字段。该表位于旧的遗留数据库中,因此绝对有可能出现意外格式。我会在接下来的几天里试试这个并报告
  • 今天能够使用您所做的更改发布一个新版本,并且它似乎正在工作!多么晦涩的问题,但感谢您的帮助!
  • @CerylWiltink 您认为您的旧数据库中有什么意想不到的格式?有没有办法识别它们?我有类似的问题,但我不确定 SQL Server 的 datetime 字段中是否有任何无效格式。我运行此查询select dateformat from sys.syslanguages where name = @@LANGUAGE 并得到mdy。我应该像答案中那样将其设置为YMD吗?你能分享你的想法吗?
  • @Fer 自从这个问题以来已经有一段时间了,所以我怕我记不住太多细节了。同时我也换了工作,所以我不能再检查这个了。挖掘我的记忆;虽然这个答案似乎是一个解决方案,但我认为它实际上是一个与数据库无关的域控制器问题。我想这可能值得尝试一下,看看是否有帮助。但更好的步骤可能是在 StackOverflow 上打开一个新问题,并完整描述您的问题,它可能会得到更好的答案。祝你好运!
  • @CerylWiltink 非常感谢。如果找不到解决方案,我将就我的问题进行更多分析并提出一个新问题。
【解决方案2】:

我知道这个问题有一个公认的答案;然而,为了增加一点味道,这个问题可以通过正确设置任务调度程序来轻松解决。

如果您的操作系统是 Win10,则在 Task Scheduler --> General Tab --> Configure for --> 上选择“Windows 10”。

在大多数情况下会很容易解决问题。

【讨论】:

    猜你喜欢
    • 2012-09-12
    • 2015-12-21
    • 2021-08-20
    • 2011-09-12
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 2016-10-31
    • 2015-10-19
    相关资源
    最近更新 更多