r - 使用 R/Shiny,在死锁时自动刷新 dbGetQuery?
问题描述
我有一个(相当复杂的)Shiny 应用程序,它正在查询我们的一个 SQL 数据库中的数据,然后将该数据格式化为一系列 ggplots。我间歇性地从 Shiny 收到以下警告:[Microsoft][ODBC SQL Server Driver][SQL Server]Transaction (Process ID 62) was deadlocked on lock | 与另一个进程通信缓冲区资源,并已被选为死锁牺牲品。重新运行事务。
我只有大约 2% 的时间会收到这个错误。我相信我会陷入僵局,因为我正在从运营商不断更新的实时系统中查询数据。基本上,我认为这意味着我对这个错误无能为力。
我想对我的应用程序进行编程以检测死锁并自动重新查询数据本身。(我可以使用 validate 将错误消息替换为手动重新运行查询的指令,但这是不可取的,因为它需要手动干预。)
简化的应用程序:(我想我已经正确复制了相关部分,可能我错过了一些括号 - 代码显然不会为你运行,因为我已经编辑了 SQL 而你没有我的本地ODBC 连接建立。)
refreshintv = 600000
pool = dbPool(drv = odbc(), dsn = "[redacted]")
onStop(function() {
poolClose(pool)
})
ui = fluidPage(
dataTableOutput("df"),
)
server = function(input, output, session) {
autorefresh = reactiveTimer(refreshintv)
refresh = reactive({
input$refresh #input$refresh comes from an action button that I haven't copied over for simplicity
if("Auto Refresh" %in% input$options) {#input$options is similarly a checkboxGroupInput
autorefresh()
}
})
df = reactive({
refresh()
sql = "[insert sql code here]"
df = dbGetQuery(pool, sql)
})
}
app = shinyApp(ui = ui, server = server)
我的第一次尝试是在 df 反应式中尝试以下内容:
while (!("data.frame" %in% class(df))) {
df = dbGetQuery(pool, sql)
}
但是上面的代码仍然出现死锁错误。似乎一旦闪亮遇到死锁错误,反应式就会返回错误,其余代码不会被评估。
我的第二种方法是创建一个反应循环。我或多或少知道这行不通,因为 df() 更改会导致 refresh() 无效,即使 class(df()) 没有更改。
refresh = reactive({
input$refresh
if("data.frame" %in% class(df())) {
invalidateLater(1)
}
if("Auto Refresh" %in% input$options) {
autorefresh()
}
})
当然,这确实会产生无限递归错误:“评估嵌套太深:无限递归/选项(表达式=)?”
我能在闪亮的错误处理中找到的所有内容基本上只是显示错误消息。如何检查死锁错误并自动刷新或使 df() 无效?这甚至可能吗?
解决方案
推荐阅读
- php - PHP 开发服务器 17 不工作
- angular - 将 Angular 与 scss 一起使用时,如何查看翻译后的 css?
- jquery - 使用缓动弹跳动画扩展 div
- python - 'Package' 对象在继承 logging.Logger 时没有属性 'level'
- r - 要替换的项目数不是替换长度的倍数 - Datacamp
- java - 从 EL 调用方法。为什么这不起作用?
- python - VS 代码中的 Python 单元测试调试
- geopy - Geopy - 地理编码器:AttributeError:“模块”对象没有属性“雅虎”
- reactjs - firebase 函数状态挂起并返回未定义
- python - Python函数读取视频并转换为帧