我正在使用这个驱动程序:https : //github.com/denisenkom/go-mssqldb并且在使用 Azure SQL 数据库标准 S3 级别的生产中,我们得到了太多 ErrBadconn -driver: Bad connection返回。
我怎样才能防止或至少优雅地处理它。这里有一些代码来展示事情是如何设置的。
一个典型的数据库函数调用
包 dal
var db *sql.DB
type Database struct{}
func (d Database) Open() {
newDB, err := sql.Open("mssql", os.Getenv("dbconnestion"))
if err != nil {
panic(err)
}
err = newDB.Ping()
if err != nil {
panic(err)
}
db = newDB
}
func (d Database) Close() {
db.Close()
}
// ... in another file
func (e *Entities) Add(entity Entity) (int64, error) {
stmt, err := db.Prepare("INSERT INTO Entities VALUES(?, ?)")
if err != nil {
return -1, err
}
defer stmt.Close()
result, err := stmt.Exec(entity.Field1, entity.Field2)
if err != nil {
return -1, err
}
return result.LastInsertId()
}
简而言之,该dal包在多个 Azure Web 应用程序和命令行 Go 应用程序之间共享。
我看不到一种模式,即那些频繁且随机发生的错误。我们正在使用 Bugsnag 来记录我们所有应用程序的错误。
为了完成,有时会达到我们的标准 S3 限制 200 个并发连接。
我在访问数据库的包上的所有地方都进行了三重检查,确保所有内容sql.Rows
都已关闭,所有db.Prepare
语句都已关闭。作为示例,典型的查询函数如下所示:
该readEntity
基本上只做Scan
上的字段。
我认为这与代码无关,单元测试在本地运行良好。有时在运行后仅部署到 Azure 一次,驱动程序:错误连接开始非常频繁地出现。
我已运行此查询以尝试查看此问题中的建议:Azure SQL server max pool size was connected 错误
select * from sys.dm_exeC_requests
但我不确定在这里我应该注意什么。
我做过/确定过的事情。
正如建议的那样,database/sql
应该处理连接池,因此为数据库连接设置一个全局变量应该没问题。
确保sql.Rows
和db.Prepare
声明在任何地方都是关闭的。
将 Azure SQL 级别提高到 S3。
我正在使用的 sql 驱动程序存在问题,如果它们空闲超过 2 分钟,则 Azure SQL 使数据库连接处于错误状态。 https://github.com/denisenkom/go-mssqldb/issues/81
database/sql
处理连接池的方式是否与 Azure SQL 数据库的管理方式不兼容。
有没有办法优雅地处理这个问题?我知道 C#/Entity Framework 有一个针对 Azure SQL 的连接弹性/重试逻辑,是不是出于类似的原因?我如何实现这一点而不必在我的错误处理中到处传递?我的意思是我不想清楚地做这样的事情:
if err == sql.ErrBadConn {
// close and re-open the global db object
// retry
}
这当然不是我唯一的选择吗?
任何帮助将非常受欢迎。谢谢
萧十郎
沧海一幻觉
相关分类