zoukankan      html  css  js  c++  java
  • go 自己封的postgresql连接池操作包

        测并发时由于使用db时没有lock,当连接数超过postgres设定的最大值时报错too many clients,于是问了下老师,老师说用连接池,一开始打开固定个数的db,每次都用这些db,而且每个db用的时候要加锁

        于是就开始想如何用lock来实现每次让进来的数据库请求排队,每次分配一个空闲的db给队列中第一个请求,但想了好久发现用锁处理起来好复杂,无法确定哪些db是空闲的,又改如何让请求排队

        后来实在想不出来,换了个思路,能不能用go的特性channal实现,猛然发现可以一开始将固定个数的db塞到channal,每次请求出队一个可用的db,用完后又将db返回channal,而且channal自带锁的功能,当channal为空时(没有db可用)请求会等待,形成了自然队列,前面的所有问题都解决了

    package myDB
    
    import (
        "database/sql"
        "errors"
    
        _ "github.com/lib/pq"
    )
    
    //var db *sql.DB = nil
    //
    //func OpenSql() error {
    //  var err error = nil
    //  db, err = sql.Open("postgres", "port=5432 user=postgres password=123456 dbname=postgres sslmode=disable")
    //  return err
    //}
    //
    //func GetDB() (*sql.DB, error) {
    //  if db == nil {
    //      return nil, errors.New("db hadn't open")
    //  }
    //  return db, nil
    //}
    
    var dbQueue chan *sql.DB
    
    func Init(queue chan *sql.DB) {
        dbQueue = queue
    }
    func open() *sql.DB {
        return <-dbQueue
    }
    func close(db *sql.DB) {
        dbQueue <- db
    }
    
    func dealResult(result sql.Result) error {
        affect, err := result.RowsAffected()
        if err != nil {
            return err
        }
        if affect <= 0 {
            return errors.New("DBExec no affect")
        }
        return nil
    }
    func ExecSql(Sql string, args ...interface{}) error {
        db := open()
        defer close(db)
        stmt, err := db.Prepare(Sql)
        if err != nil {
            return err
        }
        defer stmt.Close()
        result, err := stmt.Exec(args...)
        if err != nil {
            return err
        }
        return dealResult(result)
    }
    
    func QuerySql(Sql string, args ...interface{}) (*sql.Rows, error) {
        db := open()
        defer close(db)
        stmt, err := db.Prepare(Sql)
        if err != nil {
            return nil, err
        }
        defer stmt.Close()
        rows, err := stmt.Query(args...)
        if err != nil {
            return nil, err
        }
        return rows, err
    }
    
    func TxQuerySql(tx *sql.Tx, Sql string, args ...interface{}) (*sql.Stmt, *sql.Rows, error) {
        stmt, err := tx.Prepare(Sql)
        if err != nil {
            return nil, nil, err
        }
        rows, err := stmt.Query(args...)
        if err != nil {
            return nil, nil, err
        }
        return stmt, rows, err
    }
    
    func TxExecSql(tx *sql.Tx, Sql string, args ...interface{}) error {
        stmt, err := tx.Prepare(Sql)
        if err != nil {
            return err
        }
        defer stmt.Close()
        result, err := stmt.Exec(args...)
        if err != nil {
            return err
        }
        return dealResult(result)
    }
    
    func ExecMultiSql(Sql string, member []string, args ...interface{}) error {
        db := open()
        defer close(db)
        stmt, err := db.Prepare(Sql)
        if err != nil {
            return err
        }
        defer stmt.Close()
        for _, val := range member {
            allArgs := make([]interface{}, 0)
            allArgs = append(allArgs, val)
            allArgs = append(allArgs, args...)
            result, err := stmt.Exec(allArgs...)
            if err != nil {
                return err
            }
            err = dealResult(result)
            if err != nil {
                return err
            }
        }
        return nil
    }
    
    func TxExecMultiSql(tx *sql.Tx, Sql string, member []string, args ...interface{}) error {
        stmt, err := tx.Prepare(Sql)
        if err != nil {
            return err
        }
        defer stmt.Close()
        for _, val := range member {
            allArgs := make([]interface{}, 0)
            allArgs = append(allArgs, val)
            allArgs = append(allArgs, args...)
            result, err := stmt.Exec(allArgs...)
            if err != nil {
                return err
            }
            err = dealResult(result)
            if err != nil {
                return err
            }
        }
        return nil
    }
    

      

  • 相关阅读:
    数据结构概论
    html基础:有序列表 框架集 form表单
    html基础:定义 图片 表格
    给出2个数和一个运算符号,用函数求结果
    百钱买百鸡问题
    九九乘法表
    过路问题
    php基础:控制结构 总结
    php基础:变量,运算符总结
    php基础:数据库的含义和基本操作 增 删 改 查
  • 原文地址:https://www.cnblogs.com/cdyboke/p/6816229.html
Copyright © 2011-2022 走看看