RMySQL dbDisconnect 没有关闭数据库连接

问题描述

RMysqL 库的dbdisconnect 函数没有正确关闭数据库连接。这是我在本地测试的代码

library(RMysqL)

execute.query <- function(query){
  mydb_con <- dbConnect(MysqL(),user='username',password='pass',dbname='student',host='db_ip')
  returned_data <- dbGetQuery(mydb_con,query)
  dbdisconnect(mydb_con)
  return(returned_data)
}

for(i in c(1:100)){
  print(paste0("i = ",i));
  execute.query(paste("select Now()")); 
}

按顺序执行 100 个 sql 查询,理想情况下应该为每个查询创建和关闭新的数据库连接,但在执行上述代码后,我可以看到使用此命令 watch netstat -nat | grep {db_ip} |wc -l 数据库连接数从 0 到 20直到前 20 个查询,将其保持在 18-24 个连接,直到第 100 个查询,10 秒后程序完成执行,排空到 0 个连接。

所以我的问题是为什么 dbdisconnect 没有关闭数据库连接?有什么细微的差别我在这里不明白吗?

由于这个问题,当连接达到 1000+ 时,我的生产 R 代码(巨大的多线程遗留代码库)中出现 Failed to connect to database: Error: Can't create TCP/IP socket (24) 错误

解决方法

理想情况下,在多线程环境中,您应该将 dbConnect 保留在静态块中,并将查询执行在单独的方法中,然后 dbdisconnect atlast 说相当于 java 中的 finally 块。当您收到连接异常时,您应该尝试重新连接。如果您在多线程环境中为每个查询打开一个新连接,那么您肯定会同时打开许多文件,并且会出现此错误。

,

我更喜欢 dbSendQuery() 函数,理想情况下来自 odbc 包,正如前面的答案所述,只需保持连接打开,然后发送后续查询即可。 如果您想确保连接有效,则可以使用 dbIsValid,如果无效,请重新连接。这应该使查询执行非常安全。 注意,代码可能无法直接运行。

library(odbc)
mydb_con <- dbConnect(MySQL(),user='username',password='pass',dbname='student',host='db_ip')

execute.query <- function(query){
  result <- odbc::dbSendQuery(mydb_con,query)
  returned_data <- odbc::dbFetch(result)
  odbc::dbClearResult(result)
  return(returned_data)
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...