例如,我的闪亮应用可能会打开数据库连接
# server.R
db <- dbConnect("SQLite", DB_PATH)
shinyServer(
... # things involving db
)
现在,当Shiny会话结束时,如何确保连接db
正确关闭(通过dbDisconnect(db)
)?实际上,应该为连接到服务器的每个客户端执行清理,还是仅执行一次?
我担心多个用户一直连接到Shiny应用程序并断开连接,如果没有正确清理,他们将留下悬空的数据库连接。实际上,客户只需关闭浏览器就可以在没有警告的情况下断开连接。
答案 0 :(得分:27)
执行此操作的正确方法是使用session$onSessionEnded
指定执行清理的功能。例如,在server.R中:
cancel.onSessionEnded <- session$onSessionEnded(function() {
dbDisconnect(db)
})
然后,您可以致电cancel.onSessionEnded
撤消分配。
答案 1 :(得分:10)
预先存在的答案对我来说似乎不对。
session$onSessionEnded
可以关闭连接,但在原始问题中,所有用户只有一个连接。特别是在使用pool
时,您不希望为每个用户启动/停止单独的连接。 on.exit
直接运行,而不是等到服务器退出。我认为正确的答案是使用onStop
(https://shiny.rstudio.com/reference/shiny/latest/onStop.html)。
示例用法,来自文档:
library(shiny)
shinyApp(
ui = basicPage("onStop demo"),
server = function(input, output, session) {
onStop(function() cat("Session stopped\n"))
},
onStart = function() {
cat("Doing application setup\n")
onStop(function() {
cat("Doing application cleanup\n")
})
}
)
答案 2 :(得分:6)
Rstudio在6月份发表了一系列关于连接数据库的最佳实践的文章。简单的答案是使用池(请参阅here和here)。为简单起见,您需要定义一次池,它将处理和管理连接,根据需要打开和关闭它们。应用程序断开连接后,池将自动关闭所有连接。
不幸的是,池包不适用于SQL Server和ODBC。对于那种情况(或者如果你不想使用池),他们建议你在服务器函数 s 中使用on.exit。
例如:
getData <- reactive({
cnxn <- dbConnect(...)
on.exit(dbDisconnect(cnxn))
... # your stuff here
})
答案 3 :(得分:-1)
您可以在shinyServer函数定义中使用on.exit(dbDisconnect(db))
。