R Shiny App与R Shiny Pro中的数据库断开连接

时间:2017-10-26 19:11:42

标签: r database oracle shiny shiny-server

我有一个复杂的R Shiny应用程序,我使用R Shiny池,使用ROracle后端,连接到oracle数据库。我做了一个更简单的版本,我仍然能够重现错误。无论使用哪个数据库池/连接,似乎都有效,然后随机断开连接。在较大的应用程序中,它第一次运行,所有后续请求都失败。代码在我的笔记本电脑上通过RStudio工作正常,尽管它是通过Windows而不是Linux和R Shiny Pro部署的。我没有随时在disconnect上致电POOL

ui.R

library(shiny)
library(shinythemes)
library(dplyr)
library(readr)

ui <- fluidPage(theme = shinytheme("lumen"),
    titlePanel("Google Trend Index"),
    sidebarLayout(
        sidebarPanel(
        ),
        mainPanel(
            DT::dataTableOutput("db_studies", width = "100%"),
            DT::dataTableOutput("db_studies2", width = "100%")
        )
    )
)

server.R

library(DT)

POOL <<- MyDB::openPool()
server <- function(input, output, session) {
    output$db_studies <- DT::renderDataTable(
        DT::datatable(
            DBI::dbReadTable(POOL, "STUDY") %>%
                data.table::data.table() %>%
                dplyr::arrange(desc(DATE_CREATED)),
        )
    )

    output$db_studies2 <- DT::renderDataTable(
        DT::datatable(
            dplyr::tbl(POOL, "SAMPLE") %>%
                dplyr::filter(DATASET_ID %in% 57) %>%
                dplyr::collect(n = Inf)
        )
    )
}

池代码封装在一个包中:

openPool <- function(..., keyFilename = "db_key.RData",
    credentialsFilename = "db_login.txt",
    connectionInfoFilename = "db_connection.Rdata") {
    credentials <- getCredentials(keyFilename = keyFilename, filename = credentialsFilename)
    connectionInfo <- getConnectionInfo(filename = connectionInfoFilename)

    POOL <- pool::dbPool(...,
        drv = ROracle::Oracle(),
        dbname = paste(
            "(DESCRIPTION=",
            "(ADDRESS=(PROTOCOL=tcp)",
            "(HOST=", connectionInfo$host, ")",
            "(PORT=", connectionInfo$port, "))",
            "(CONNECT_DATA=(SID=", connectionInfo$sid, ")))", sep = ""),
        host = connectionInfo$host,
        port = connectionInfo$port,
        username = credentials$username,
        password = credentials$password
    )

    POOL
}

包的目的是分离数据库凭据和处理,但是对于上面的简单测试,我直接查询数据库,并且在几次刷新之后,数据库池变得无效并失败。

我最初实例化POOL对象,然后传递它。看看没有一个例子是这样做的,我改为创建了一个全局POOL对象,然后我尝试直接引用它。我还试图通过openConnection或通过池checkout使用直接连接,并在几次尝试后断开连接。

1 个答案:

答案 0 :(得分:1)

你可以做的事情很少:

## In your pool function, put maximum connection in drv as below 
drv = ROracle::Oracle(max.con=128)

此外,池泄漏连接始终存在问题。所以,在你的情况下,我认为它达到最大连接,默认为16。为了避免这种情况,我建议在从oracle数据库加载数据后使用下面的行。这将删除所有泄露的连接。

lapply(dbListConnections(Oracle()), dbDisconnect)