使用pq.Array向PostgreSQL插入数据时Golang代码卡住问题求助
问题描述
我用Go编写了向PostgreSQL插入两个字符串和一个数组的代码,数据库连接正常,但执行到检查点sampe A后就卡住了。尝试过不含数组的插入操作和查询语句,均能正常执行。代码如下:
package main import ( "backend_hotel/modules" "context" "database/sql" "fmt" "github.com/lib/pq" _ "github.com/lib/pq" ) var db *sql.DB var Cancel context.CancelFunc func main() { modules.InitiateGlobalVariables(false) var errDB error psqlInfo := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", modules.MapConfig["rhanovDatabaseHost"], modules.MapConfig["rhanovDatabasePort"], modules.MapConfig["rhanovDatabaseUser"], modules.MapConfig["rhanovDatabasePass"], modules.MapConfig["rhanovDatabaseName"]) db, errDB = sql.Open("postgres", psqlInfo) if errDB != nil { modules.DoLog("INFO", "", "HotelUserDB", "main", "Failed to connect to database Rhanov server. Error!", true, errDB) panic(errDB) } else { modules.DoLog("INFO", "", "HotelUserDB", "main", "Success to connect to database Rhanov.", false, nil) } insertQuery := `INSERT INTO user_history.last_multi_flight_search(user_id, query_string, flight_ids) VALUES ($1, $2, $3)` fmt.Println("sampe A") insertArray := []string{"Test 1", "test 2", "test 3", "test 4", "test 5"} result, err := db.Exec(insertQuery, "001", "iniQueryString", pq.Array(insertArray)) if err != nil { fmt.Println("sampe B") fmt.Println(err) } else { fmt.Println("sampe C") fmt.Println(result) } fmt.Println("sampe D") }
排查与解决方法
核对表字段类型
确认user_history.last_multi_flight_search表的flight_ids字段类型为text[](或对应字符串数组的类型),若类型不匹配(比如设为int[]或其他非字符串数组类型),会导致参数解析阻塞,需调整字段类型或数组元素类型。添加上下文超时,强制获取错误信息
当前代码未设置超时,数据库操作卡住后会无限等待。给db.Exec替换为带超时上下文的db.ExecContext,能快速定位阻塞原因:import "time" // 需要导入time包 // ... 其他代码 ... ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() result, err := db.ExecContext(ctx, insertQuery, "001", "iniQueryString", pq.Array(insertArray))超时后会返回明确错误,帮助判断是数据库端阻塞还是参数问题。
检查数据库锁与事务
登录PostgreSQL执行以下SQL,查看是否有未提交事务或锁阻塞插入:-- 查看 idle in transaction 的进程 SELECT pid, query, state FROM pg_stat_activity WHERE state = 'idle in transaction'; -- 查看未授予的锁 SELECT * FROM pg_locks WHERE NOT granted;若发现异常进程,用
pg_terminate_backend(pid)终止后重试。单独验证数组参数传递
先隔离数组参数的使用,测试pq.Array是否能正常与数据库交互:rows, err := db.Query("SELECT $1::text[]", pq.Array(insertArray)) if err != nil { fmt.Println(err) } else { defer rows.Close() var arr []string for rows.Next() { err := rows.Scan(pq.Array(&arr)) if err != nil { fmt.Println(err) } else { fmt.Println("数组传递正常:", arr) } } }如果这一步报错,说明
pq.Array的使用存在问题,需检查依赖版本或参数类型。配置连接池参数
显式设置连接池参数,避免连接耗尽或闲置问题:db.SetMaxOpenConns(10) db.SetMaxIdleConns(5) db.SetConnMaxLifetime(30*time.Second)
内容的提问来源于stack exchange,提问作者Rakai Seto
相关产品推荐
相关产品推荐

