- 使用
sync.Mutex
和连接池:
- 连接池可以有效管理数据库连接,避免频繁创建和销毁连接。
sync.Mutex
用于保护对连接池的操作,防止竞争。
package main
import (
"database/sql"
"fmt"
"sync"
_ "github.com/lib/pq" // 以PostgreSQL为例,根据实际数据库选择
)
// 定义数据库连接池结构体
type ConnectionPool struct {
pool []*sql.DB
mutex sync.Mutex
capacity int
}
// 创建连接池
func NewConnectionPool(capacity int) *ConnectionPool {
pool := make([]*sql.DB, 0, capacity)
for i := 0; i < capacity; i++ {
db, err := sql.Open("postgres", "user=postgres dbname=mydb sslmode=disable")
if err != nil {
panic(err)
}
pool = append(pool, db)
}
return &ConnectionPool{
pool: pool,
capacity: capacity,
}
}
// 获取连接
func (cp *ConnectionPool) GetConnection() *sql.DB {
cp.mutex.Lock()
defer cp.mutex.Unlock()
if len(cp.pool) == 0 {
// 可以选择等待连接可用,或者返回错误
return nil
}
conn := cp.pool[0]
cp.pool = cp.pool[1:]
return conn
}
// 释放连接
func (cp *ConnectionPool) ReleaseConnection(conn *sql.DB) {
cp.mutex.Lock()
defer cp.mutex.Unlock()
if len(cp.pool) >= cp.capacity {
// 超出容量时可以选择关闭连接
conn.Close()
return
}
cp.pool = append(cp.pool, conn)
}
- 简要说明:
ConnectionPool
结构体包含一个连接切片pool
用于存储数据库连接,mutex
用于同步访问连接池,capacity
表示连接池的最大容量。
NewConnectionPool
函数初始化连接池,创建指定数量的数据库连接并添加到池中。
GetConnection
方法在获取连接时,先锁定mutex
,从连接池中取出一个连接并从池中移除,使用defer
确保解锁mutex
。
ReleaseConnection
方法在释放连接时,同样先锁定mutex
,如果连接池未满则将连接放回池中,否则关闭连接。这样设计可以确保在多个goroutine并发访问时,数据库连接能正确分配、使用和释放,避免资源泄露和竞争问题。