mirror of
https://gitee.com/johng/gf
synced 2026-06-07 02:12:11 +08:00
fix issue: database connection pool does not work expectly
This commit is contained in:
@ -91,7 +91,7 @@ type Db struct {
|
||||
charr string // SQL安全符号(右)
|
||||
debug *gtype.Bool // (默认关闭)是否开启调试模式,当开启时会启用一些调试特性
|
||||
sqls *gring.Ring // (debug=true时有效)已执行的SQL列表
|
||||
cache *gcache.Cache // 查询缓存,需要注意的是,事务查询不支持缓存
|
||||
cache *gcache.Cache // 数据库缓存,包括底层连接池对象缓存及查询缓存;需要注意的是,事务查询不支持查询缓存
|
||||
maxIdleConnCount *gtype.Int // 连接池最大限制的连接数
|
||||
maxOpenConnCount *gtype.Int // 连接池最大打开的连接数
|
||||
maxConnLifetime *gtype.Int // (单位秒)连接对象可重复使用的时间长度
|
||||
@ -248,40 +248,51 @@ func getLinkByType(dbType string) (Link, error) {
|
||||
}
|
||||
|
||||
// 获得底层数据库链接对象
|
||||
func (db *Db) getSqlDb(master bool) (*sql.DB, error) {
|
||||
func (db *Db) getSqlDb(master bool) (sqlDb *sql.DB, err error) {
|
||||
// 负载均衡
|
||||
node, err := getConfigNodeByGroup(db.group, master)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 类型对象
|
||||
link, err := getLinkByType(node.Type)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sqlDb, err := link.Open(node)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if node.MaxIdleConnCount > 0 {
|
||||
sqlDb.SetMaxIdleConns(node.MaxIdleConnCount)
|
||||
}
|
||||
if n := db.maxIdleConnCount.Val(); n > 0 {
|
||||
sqlDb.SetMaxIdleConns(n)
|
||||
// 检查缓存连接池对象
|
||||
cacheKey := node.String()
|
||||
if v := db.cache.Get(cacheKey); v != nil {
|
||||
return v.(*sql.DB), nil
|
||||
}
|
||||
v := db.cache.GetOrSetFuncLock(node.String(), func() interface{} {
|
||||
sqlDb, err = link.Open(node)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.MaxOpenConnCount > 0 {
|
||||
sqlDb.SetMaxOpenConns(node.MaxOpenConnCount)
|
||||
}
|
||||
if n := db.maxOpenConnCount.Val(); n > 0 {
|
||||
sqlDb.SetMaxOpenConns(n)
|
||||
}
|
||||
if n := db.maxIdleConnCount.Val(); n > 0 {
|
||||
sqlDb.SetMaxIdleConns(n)
|
||||
} else if node.MaxIdleConnCount > 0 {
|
||||
sqlDb.SetMaxIdleConns(node.MaxIdleConnCount)
|
||||
}
|
||||
|
||||
if node.MaxConnLifetime > 0 {
|
||||
sqlDb.SetConnMaxLifetime(time.Duration(node.MaxConnLifetime) * time.Second)
|
||||
if n := db.maxOpenConnCount.Val(); n > 0 {
|
||||
sqlDb.SetMaxOpenConns(n)
|
||||
} else if node.MaxOpenConnCount > 0 {
|
||||
sqlDb.SetMaxOpenConns(node.MaxOpenConnCount)
|
||||
}
|
||||
|
||||
if n := db.maxConnLifetime.Val(); n > 0 {
|
||||
sqlDb.SetConnMaxLifetime(time.Duration(n) * time.Second)
|
||||
} else if node.MaxConnLifetime > 0 {
|
||||
sqlDb.SetConnMaxLifetime(time.Duration(node.MaxConnLifetime) * time.Second)
|
||||
}
|
||||
return sqlDb
|
||||
}, 0)
|
||||
if v != nil && sqlDb == nil {
|
||||
sqlDb = v.(*sql.DB)
|
||||
}
|
||||
if n := db.maxConnLifetime.Val(); n > 0 {
|
||||
sqlDb.SetConnMaxLifetime(time.Duration(n) * time.Second)
|
||||
}
|
||||
return sqlDb, nil
|
||||
return
|
||||
}
|
||||
|
||||
// 创建底层数据库master链接对象
|
||||
|
||||
@ -89,7 +89,6 @@ func (db *Db) Query(query string, args ...interface{}) (*sql.Rows, error) {
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
defer slave.Close()
|
||||
p := db.link.handleSqlBeforeExec(&query)
|
||||
if db.debug.Val() {
|
||||
militime1 := gtime.Millisecond()
|
||||
@ -125,7 +124,6 @@ func (db *Db) Exec(query string, args ...interface{}) (sql.Result, error) {
|
||||
if err != nil {
|
||||
return nil,err
|
||||
}
|
||||
defer master.Close()
|
||||
p := db.link.handleSqlBeforeExec(&query)
|
||||
if db.debug.Val() {
|
||||
militime1 := gtime.Millisecond()
|
||||
@ -259,12 +257,10 @@ func (db *Db) Select(tables, fields string, condition interface{}, groupBy, orde
|
||||
}
|
||||
|
||||
// sql预处理,执行完成后调用返回值sql.Stmt.Exec完成sql操作
|
||||
// 记得调用sql.Stmt.Close关闭操作对象
|
||||
func (db *Db) Prepare(query string) (*sql.Stmt, error) {
|
||||
if master, err := db.Master(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
defer master.Close()
|
||||
return master.Prepare(query)
|
||||
}
|
||||
}
|
||||
@ -274,7 +270,6 @@ func (db *Db) PingMaster() error {
|
||||
if master, err := db.Master(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
defer master.Close()
|
||||
return master.Ping()
|
||||
}
|
||||
}
|
||||
@ -284,7 +279,6 @@ func (db *Db) PingSlave() error {
|
||||
if slave, err := db.Slave(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
defer slave.Close()
|
||||
return slave.Ping()
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
package gdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@ -134,4 +135,15 @@ func (db *Db) SetMaxOpenConns(n int) {
|
||||
// 如果 d <= 0 表示该链接会一直重复利用
|
||||
func (db *Db) SetConnMaxLifetime(n int) {
|
||||
db.maxConnLifetime.Set(n)
|
||||
}
|
||||
|
||||
// 节点配置转换为字符串
|
||||
func (node *ConfigNode) String() string {
|
||||
if node.Linkinfo != "" {
|
||||
return node.Linkinfo
|
||||
}
|
||||
return fmt.Sprintf(`%s@%s:%s,%s,%s,%s,%s,%d-%d-%d`, node.User, node.Host, node.Port,
|
||||
node.Name, node.Type, node.Role, node.Charset,
|
||||
node.MaxIdleConnCount, node.MaxOpenConnCount, node.MaxConnLifetime,
|
||||
)
|
||||
}
|
||||
@ -27,16 +27,12 @@ type Tx struct {
|
||||
|
||||
// 事务操作,提交
|
||||
func (tx *Tx) Commit() error {
|
||||
err := tx.tx.Commit()
|
||||
tx.master.Close()
|
||||
return err
|
||||
return tx.tx.Commit()
|
||||
}
|
||||
|
||||
// 事务操作,回滚
|
||||
func (tx *Tx) Rollback() error {
|
||||
err := tx.tx.Rollback()
|
||||
tx.master.Close()
|
||||
return err
|
||||
return tx.tx.Rollback()
|
||||
}
|
||||
|
||||
// (事务)数据库sql查询操作,主要执行查询
|
||||
@ -193,7 +189,6 @@ func (tx *Tx) Select(tables, fields string, condition interface{}, groupBy, orde
|
||||
}
|
||||
|
||||
// sql预处理,执行完成后调用返回值sql.Stmt.Exec完成sql操作
|
||||
// 记得调用sql.Stmt.Close关闭操作对象
|
||||
func (tx *Tx) Prepare(query string) (*sql.Stmt, error) {
|
||||
return tx.tx.Prepare(query)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user