The following test program opens connections to 2 Postgresql databases and then spawns 200 goroutines. Each goroutine runs some Begin/Commit/Rollback commands and exits. For me, the program hangs after a few goroutines are successful. The goroutines are hanging in the initial dbA.Begin() statement.
If I comment out the Commit/Begin pair in the middle, the program runs to completion.
Clearly I'm doing something wrong, but I've been banging my head trying to figure out what it is. Can someone enlighten me? This is Go 1.5, Postgresql 9.3. The program is running on Mac 10.10.5, the databases are on CentOS 6.5.
Any help would be greatly appreciated!
Thanks,
Mark
package main
import (
"database/sql"
"log"
"sync"
)
func main() {
dbA, err := sql.Open("postgres", "user=user password=passwd host=127.0.0.1 dbname=db1 sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer dbA.Close()
dbA.SetMaxIdleConns(0)
dbA.SetMaxOpenConns(5)
dbB, err := sql.Open("postgres", "user=user password=passwd host=127.0.0.1 dbname=db2 sslmode=disable")
if err != nil {
log.Fatal(err)
}
defer dbB.Close()
dbB.SetMaxIdleConns(0)
dbB.SetMaxOpenConns(5)
var wg sync.WaitGroup
for i := 0; i < 200; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
log.Printf("Start %d", id)
txA, err := dbA.Begin()
log.Printf("Begin A done %d", id)
if err != nil {
log.Fatal(err)
}
txB, err := dbB.Begin()
log.Printf("Begin B done %d", id)
if err != nil {
log.Fatal(err)
}
// If you comment out this Commit and Begin pair, it completes normally.
err = txA.Commit()
log.Printf("Commit A done %d", id)
if err != nil {
log.Fatal(err)
}
txA, err = dbA.Begin()
log.Printf("Begin 2 A done %d", id)
if err != nil {
log.Fatal(err)
}
err = txA.Rollback()
log.Printf("Rollback A done %d", id)
if err != nil {
log.Fatal(err)
}
err = txB.Rollback()
log.Printf("Rollback B done %d", id)
if err != nil {
log.Fatal(err)
}
log.Printf("End %d", id)
}(i)
}
wg.Wait()
}