【问题标题】:Increase connection attempt with DBI增加与 DBI 的连接尝试
【发布时间】:2022-01-26 05:11:13
【问题描述】:

我正在尝试构建一个闪亮的应用程序,它将使用 DBI 连接到一个不稳定的 PostgreSQL 数据库。当数据库稳定时它可以正常工作,但只要数据库变慢或暂时停止,就会出现 Whitelabel Error。如何配置我的应用程序,使其在抛出错误之前继续尝试连接多次?示例代码如下:

library(shiny)
library(DBI)

con <- dbConnect(
  RPostgres::Postgres(),
  host = "myip",
  port = "myport",
  dbname = "mydb",
  user = "user",
  password = "password"
)

ui <- fluidPage(
  tableOutput("mytable")
)

server <- function(input, output, session){
  output$mytable <- renderTable(
    dbGetQuery(
      con,
      "select * from mytable;"
    )
  )
}

shinyApp(ui, server)

【问题讨论】:

  • 看看?tryCatch
  • 我应该只使用带有 dbConnect 的 tryCatch,还是每个 dbGetQuery?
  • 我认为您的问题的答案是:both,并使用单独的恢复逻辑。也就是说,如果dbConnect 失败,那么我将推断您的大多数应用程序不再能够完成其工作。如果特定查询失败,可能是由于(1)您更改了查询并且没有充分测试它;或 (2) 用户输入了不适当的输入(即在表单字段中),您可能应该在尝试 dbGetQuery 之前进行一些错误清理。 (这两个原因都是由于对应用程序的测试不足。)可能 (3) 数据库有其他故障,超出您的控制范围。

标签: r shiny dbi


【解决方案1】:

我们可以按照@r2evans 的建议尝试purrr::insistently()rate_backoff,以重试查询在每次之间等待更长的时间,在这种情况下最多为4。

library(shiny)
library(DBI)
library(purrr)

con <- dbConnect(
  RPostgres::Postgres(),
  host = "myip",
  port = "myport",
  dbname = "mydb",
  user = "user",
  password = "password"
)

my_rate <- rate_backoff(
  pause_base = 1,
  pause_cap = 60,
  pause_min = 1,
  max_times = 4,
  jitter = FALSE
)


ui <- fluidPage(
  tableOutput("mytable")
)

server <- function(input, output, session) {
  output$mytable <- renderTable(
    insistently(~
    dbGetQuery(
      con,
      "select * from mytable;"
    ), rate = my_rate, quiet = FALSE)()
  )
}

shinyApp(ui, server)

【讨论】:

  • 强烈鼓励使用max_times(也许rate_backoff而不是rate_delay),否则这个应用程序成为每个人的责任时间 (1) 查询被更改,(2) 数据库处于某种维护模式,(3) 数据库已经因其他原因发生故障,现在这成为更多的问题,每秒 i>.
  • @r2evans 感谢您指出这一点。我编辑了我的答案。
  • 非常感谢您的回答。我还不能投票,但一旦我获得足够的声望,我就会这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 2021-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多