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

Go语言使用Google Cloud Spanner出现invalid session pool错误的解决方法

问题描述

我使用Spanner库编写了Go代码,创建Spanner客户端时未报错,但执行查询时出现invalid session pool错误,代码及错误日志如下:

代码

package main

import (
    "log/slog"
    "log"
    "fmt"
    "context"

    "cloud.google.com/go/spanner"
)


func createClient(ctx context.Context, db string) (*spanner.Client, error) {
    sessionPoolConfig := spanner.SessionPoolConfig{
        TrackSessionHandles: true,
        InactiveTransactionRemovalOptions: spanner.InactiveTransactionRemovalOptions{
            ActionOnInactiveTransaction: spanner.WarnAndClose,
        },
    }
    dataClient, err := spanner.NewClientWithConfig(
        ctx, db, spanner.ClientConfig{SessionPoolConfig: sessionPoolConfig},
    )
        if err != nil {
        slog.Error("failed to create the spanner client", "err", err)
                return nil, err
        }
        defer dataClient.Close()

        _ = dataClient

        return dataClient, nil
}

var dbLink = "projects/PROJECT_NAME/instances/INSTANCE_NAME/databases/DATABASE_NAME"

func main() {
    ctx := context.Background()

    snapperClient, err := createClient(ctx, dbLink)
    if err != nil {
        log.Fatalf("failed to create a spanner client, error=%s", err.Error())
}

    row, err := spannerClient.Single().ReadRow(ctx, "DATA_TABLE", spanner.Key{THE_KEY}, []string{"THE_COLUMN"})
    if err != nil {
        slog.Error("failed to get the DATA from spanner", "error", err.Error())
        return nil, err
}
...
}

错误日志

2023/11/30 22:40:03 ERROR failed to get the DATA from spanner id=4 error="spanner: code = \"InvalidArgument\", desc = \"invalid session pool\""

请问如何修复这个invalid session pool错误?


解决方案

导致该错误的核心问题有三个,逐一修复即可:

  1. 移除createClient函数内的defer dataClient.Close()
    你在创建客户端后立刻通过defer关闭了它,函数返回时客户端已被销毁,后续main函数使用这个已关闭的客户端,就会触发会话池无效的错误。正确做法是将客户端关闭逻辑移到调用方(即main函数):
    修改后的createClient函数:

    func createClient(ctx context.Context, db string) (*spanner.Client, error) {
        sessionPoolConfig := spanner.SessionPoolConfig{
            TrackSessionHandles: true,
            InactiveTransactionRemovalOptions: spanner.InactiveTransactionRemovalOptions{
                ActionOnInactiveTransaction: spanner.WarnAndClose,
            },
        }
        dataClient, err := spanner.NewClientWithConfig(
            ctx, db, spanner.ClientConfig{SessionPoolConfig: sessionPoolConfig},
        )
        if err != nil {
            slog.Error("failed to create the spanner client", "err", err)
            return nil, err
        }
        // 移除此处的defer Close()
        return dataClient, nil
    }
    

    在main函数中添加关闭逻辑:

    func main() {
        ctx := context.Background()
    
        snapperClient, err := createClient(ctx, dbLink)
        if err != nil {
            log.Fatalf("failed to create a spanner client, error=%s", err.Error())
        }
        defer snapperClient.Close() // 在此处添加defer关闭客户端
    
        // 后续查询逻辑...
    }
    
  2. 修正变量名拼写错误
    main函数中创建的客户端变量是snapperClient,但查询时误用了spannerClient,需统一变量名:

    row, err := snapperClient.Single().ReadRow(ctx, "DATA_TABLE", spanner.Key{THE_KEY}, []string{"THE_COLUMN"})
    
  3. 修复main函数的错误返回逻辑
    main函数的返回类型为func main(),不能返回nil, err,需改为log.Fatal(err)或其他合法的错误处理方式:

    if err != nil {
        slog.Error("failed to get the DATA from spanner", "error", err.Error())
        log.Fatal(err)
    }
    

内容的提问来源于stack exchange,提问作者MLev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:46:34