You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:45:56