2015-01-25 4 views
7

나는 github.com/go-sql-driver/mysql 드라이버를 사용하고 있습니다.Golang, mysql : 오류 1040 : 너무 많은 연결

rows, err := db.Query("select name from beehives") 
if err != nil { 
    panic(err) 
}  
defer rows.Close() 

두 번째 :

err = db.QueryRow("select id, secret, shortname from beehives where shortname = ?", beehive).Scan(&id, &secre 
    switch { 
    case err == sql.ErrNoRows: 
     err = errors.New("Beehive '"+beehive+"' not found.") 
    case err != nil: 
     panic("loginBeehive: "+ err.Error()) 
    default: 
     // ... do the work 

당시 나는 다음과 MySQL의 코드를 200 회라고 두 가지 기능을 가지고

db, err := sql.Open("mysql", str) 

:

나는 데이터베이스를 열 첫 번째는 패닝입니다.

데이터베이스를 한 번 열었을 때 둘 이상의 연결이 어떻게 될 수 있으며 어떻게 닫을 수 있습니까?

답변

11

sql.Open doesn't really open a connection to your database.

sql.DB는 데이터베이스에 대한 연결 풀을 유지 관리합니다. 데이터베이스를 쿼리 할 때마다 프로그램은이 풀에서 연결을 시도하거나 그렇지 않으면 새 풀을 만듭니다. 이러한 연결은 일단 닫으면 다시 풀에 저장됩니다.

이것은 rows.Close()입니다. Scan(...)을 호출하면 db.QueryRow("...")이 내부적으로 동일한 작업을 수행합니다.

기본 문제는 너무 많은 쿼리를 생성하는 것인데, 각 쿼리에는 연결이 필요하지만 연결 속도는 충분히 빠르지 않습니다. 이렇게하면 프로그램이 각 쿼리에 대해 새로운 연결을 만들어야합니다.

sql.DB에서 SetMaxOpenConns을 호출하여 프로그램에서 사용하는 최대 연결 수를 제한 할 수 있습니다.

자세한 내용은 http://go-database-sql.org/surprises.html을 참조하십시오.

2

연결을 다시 사용하려면 준비된 문 db.Prepare(query string) (*Stmt, error)stmt.Query 또는 stmt.Execstmt.Close을 사용해보십시오.

3

sql.Open에서 되돌아 오는 *DB 개체는 단일 연결에 해당하지 않습니다. 데이터베이스에 대한 핸들로서 더 나은 생각입니다. 연결 풀을 관리합니다.

공회전 연결을 위해 `(*DB).SetMaxOpenConnsits pair으로 열린 연결 수를 제어 할 수 있습니다.

기본적으로 여기에서 일어나는 일은 db.Querydb.QueryRow이 연결을 직접 획득하려고 시도하고 DB 핸들이 동시 연결 수에 제한을 두지 않으므로 mysql이 처리 할 수있는 것보다 더 많은 코드가 열릴 때 패닉이 발생합니다 .

관련 문제