我正在使用此驱动程序:https://github.com/denisenkom/go-mssqldb以及使用Azure SQL数据库标准S3级别进行生产时,我们得到的方式太多了ErrBadconn - driver: Bad connection
返回。如何使用Azure SQL数据库来防止/处理ErrBadConn
我怎样才能防止或至少优雅地处理。这里有一些代码来展示如何设置。
典型的数据库函数调用
包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()
}
在网页API,以便在短
func main() {
db := dal.Database{}
db.Open()
defer db.Close()
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
entities := &dal.Entites{}
id, err := entities.Add(dal.Entity{Field1: "a", Field2: "b"})
if err != nil {
// here all across my web api and other web package or cli cmd that uses the dal I'm getting random ErrBadConn
}
})
}
,所述dal
包跨越多个天青网络应用和命令行共享去应用程序。
我看不到一个模式,那些频繁且随机发生的错误。我们使用Bugsnag来记录我们所有应用程序中的错误。
为了完成,有时我们达到了200个并发连接的标准S3限制。
我已经三重检查访问数据库的包上的所有地方,确保所有sql.Rows
已关闭,所有db.Prepare
语句都已关闭。作为和这里的例子是一个典型的查询功能的样子:
func (e *Entities) GetByID(id int64) ([]Entity, error) {
rows, err := db.Query("SELECT * FROM Entities WHERE ID = ?", id)
if err != nil {
return nil, err
}
defer rows.Close()
var results []Entity
for rows.Next() {
var r Entity
err := readEntity(rows, &r)
if err != nil {
return nil, err
}
results = append(results, r)
}
if err = rows.Err(); err != nil {
return nil, err
}
return results, nil
}
的readEntity
基本上只做上的字段Scan
。
我不认为它是代码相关的,单元测试在本地运行良好。它只是在有时运行驱动程序后才部署到Azure:连接不良开始频繁出现。
我跑这个查询尝试,看看在这个问题建议:Azure SQL server max pool size was reached error
select * from sys.dm_exeC_requests
但我不完全相信,我应该在这里关注。
我已经做了/确定的事情。
由于它的建议,该
database/sql
应该处理连接池,所以有数据库连接的全局变量应该罚款。确保
sql.Rows
和db.Prepare
声明处处关闭。将Azure SQL级别提高到S3。
有一个为我使用的SQL驱动程序的问题,谈到SQL Azure中进行数据库连接,如果他们空转多吴丹2分钟糟糕的状态。 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
}
这当然不是我唯一的选择吗?
任何帮助将非常受欢迎。 谢谢
是你的应用程序和SQL Azure的数据库在同一地区举行? – Daredevil
@Abhimanyu是的,他们都在同一地区北部中央美国 –
这是正确的。重试逻辑用于这些场景。那么将代码复制到GO将会很好:https://azure.microsoft.com/en-us/documentation/articles/sql-database-develop-csharp-retry-windows/ –