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
    }
    

      

  • 相关阅读:
    173. Binary Search Tree Iterator
    199. Binary Tree Right Side View
    230. Kth Smallest Element in a BST
    236. Lowest Common Ancestor of a Binary Tree
    337. House Robber III
    449. Serialize and Deserialize BST
    508. Most Frequent Subtree Sum
    513. Find Bottom Left Tree Value
    129. Sum Root to Leaf Numbers
    652. Find Duplicate Subtrees
  • 原文地址:https://www.cnblogs.com/cdyboke/p/6816229.html
Copyright © 2011-2022 走看看