【问题标题】:How to keep a persistent connection to SQL Server using Ruby Sequel and Tiny_TDS while in a loop如何在循环中使用 Ruby Sequel 和 Tiny_TDS 保持与 SQL Server 的持久连接
【发布时间】:2014-04-11 04:15:17
【问题描述】:

我有一个 ruby​​ 脚本需要在服务器上持续运行。我已经使用 daemon gem 对其进行了守护,并且在我的脚本中我让它在无限循环中运行,因为 daemon gem 处理启动和停止启动我的脚本的进程。在我的脚本中,我首先使用 Sequel gem 和 tiny_tds 设置我的数据库实例。像这样:

DB = Sequel.connect(adapter: 'tinytds', host: MSSQLHost, database: MSSQLDatabase, user: MSSQLUser, password: MSSQLPassword)

然后我有一个loop do,这是我的无限循环。在其中,我使用DB.test_connection 测试是否有连接,然后我每隔一秒左右查询一次数据库以检查是否有新内容,使用如下查询:

DB['SELECT * FROM dbo.[MyTable]'].all do |row|
    # MY logic here
    # As part of my logic I test to see if I need to delete this row in the table and if so I use
    DB.run('DELETE FROM dbo.[MyTable] WHERE some condition')
end

然后在我的逻辑结束时,就在我再次循环之前,我这样做:

sleep 1
DB.disconnect

所有这些都可以正常工作大约一个小时到一个半小时,所有检查表、执行逻辑、删除行等,然后它就会死掉并给我这个错误消息TinyTds::Error: Adaptive Server connection timed out

我的问题,为什么会这样?我需要以不同的方式重新格式化我的代码吗?为什么 DB.test_connection 不做它宣传的事情?上面的文档说它会检查连接池中的连接,如果找到就使用它,否则会创建一个新的。

任何帮助将不胜感激

【问题讨论】:

    标签: ruby sequel freetds tiny-tds


    【解决方案1】:

    DB.test_connection 只是从连接池中获取连接,它不检查连接是否仍然有效(它必须在某一时刻有效,否则它不会在池中)。如果没有实际发送查询,连接就不可能仍然有效。如果您想自动执行此操作,可以使用 Sequel 附带的 connection_validator 扩展。

    如果您在 fork 之前加载 Sequel,则需要确保在 fork 之前调用 DB.disconnect,否则您可能会导致多个 fork 进程共享同一连接,这可能会导致许多不同的问题。

    【讨论】:

    • 所以,这似乎并没有解决它,即使使用 connection_validator 仍然超时。我现在已经将它设置为使用超时来测试每个请求的连接,看看这是否能解决这个问题。在这样的无限循环中使用数据库实例时的最佳做法是什么?
    【解决方案2】:

    我最后只是在其中放置了一条救援语句来捕获这个问题,然后重新运行我的代码行来创建数据库实例,是的,它在我的日志中发出了一个警告,说明已经设置了该实例,但我猜我可以让它不是一个常数,一个会消失的。无论如何,它现在似乎正在工作,而且它确实超时的时间,我正在从这些中优雅地恢复。我只是希望我能弄清楚为什么它会像现在这样断开连接。

    【讨论】:

    • @user350013 任何进一步的见解?
    猜你喜欢
    • 1970-01-01
    • 2022-10-25
    • 2011-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    相关资源
    最近更新 更多