在Go语言中,要保证单个请求始终复用同一个MySQL连接,可通过以下方法实现:
1. 使用gorilla/context库(无Web框架时)- 原理:gorilla/context库可在请求作用域内存储和共享数据,避免重复创建连接。
- 实现步骤:
初始化连接池:在程序启动时创建MySQL连接池(如database/sql.DB)。
中间件处理:在HTTP请求处理链中,通过中间件从连接池获取连接,并存储到gorilla/context中。
复用连接:后续处理函数从gorilla/context中获取同一连接。
清理资源:请求结束后释放连接回连接池。
- 示例代码:import ( "database/sql" "net/http" "github.com/gorilla/context")var db *sql.DB // 全局连接池func middleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 从连接池获取连接 conn, err := db.Conn(context.Background()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // 存储连接到请求作用域 context.Set(r, "db_conn", conn) defer func() { // 请求结束后释放连接回连接池 if c := context.Get(r, "db_conn"); c != nil { c.(*sql.Conn).Close() } }() next.ServeHTTP(w, r) })}func handler(w http.ResponseWriter, r *http.Request) { // 从请求作用域获取连接 if conn := context.Get(r, "db_conn"); conn != nil { // 使用conn执行数据库操作 _, _ = conn.(*sql.Conn).Exec("SELECT 1") }}
2. 使用Web框架内置功能(如Gin)3. 关键注意事项- 连接池配置:合理设置database/sql.DB的SetMaxOpenConns和SetMaxIdleConns,避免连接泄漏或资源耗尽。
- 错误处理:确保连接获取失败时能正确返回错误,避免空指针异常。
- 并发安全:database/sql.DB本身是并发安全的,但单个连接(*sql.Conn)不能跨请求共享。
- 性能优化:复用连接可减少握手开销,但需监控连接池状态,避免长时间占用导致阻塞。
4. 替代方案对比- 手动传递连接:在函数调用链中显式传递连接对象,但代码耦合度高,不推荐。
- 单例模式:全局共享单个连接,无法支持并发请求,仅适用于单线程场景。
- ORM框架:如GORM支持连接复用,但需依赖框架实现,灵活性较低。
通过上述方法,可有效保证单个请求内复用同一MySQL连接,提升数据库交互效率。推荐根据项目是否使用Web框架选择对应方案。