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

Golang SDK创建Neo4j数据库后无法写入数据的问题求助

问题分析

你遇到的Neo.TransientError.General.DatabaseUnavailable错误,核心原因是Neo4j创建数据库后需要一定时间完成初始化启动,你在数据库刚创建完成就立刻尝试建立会话写入数据,此时数据库还未进入可用状态,导致无法获取路由表。

解决方案

1. 增加数据库就绪等待逻辑

创建数据库后,循环检查目标数据库的状态,直到它进入online状态,再继续后续的数据导入操作。可以通过执行SHOW DATABASE $dbName语句来查询状态。

2. 修复Drop数据库的语法错误

你的defer语句里,删除数据库用的是drop database %d,这里应该使用完整的数据库名graphName,而不是直接用originid,否则会删除错误的数据库。

3. 优化后的完整代码示例

graphName := fmt.Sprintf("graph%d", originid)
// 创建一个neo4j数据库
o.Originid = originid
rootSession := l.svcCtx.Neo4jConn.NewSession(l.ctx, neo4j.SessionConfig{})
_, err = rootSession.Run(l.ctx, fmt.Sprintf("create database %s", graphName), nil)
if err != nil {
    l.Error("创建数据库失败", req, err.Error())
    return &types.Response{
        Status:  false,
        Message: "创建失败",
    }, nil
}
rootSession.Close(l.ctx)

// 等待数据库进入可用状态
waitSession := l.svcCtx.Neo4jConn.NewSession(l.ctx, neo4j.SessionConfig{})
defer waitSession.Close(l.ctx)
maxWaitTime := 30 * time.Second // 最大等待30秒
checkInterval := 1 * time.Second // 每1秒检查一次
startTime := time.Now()

for time.Since(startTime) < maxWaitTime {
    result, err := waitSession.Run(l.ctx, "SHOW DATABASE $dbName YIELD name, currentStatus", map[string]interface{}{
        "dbName": graphName,
    })
    if err != nil {
        time.Sleep(checkInterval)
        continue
    }

    var dbStatus struct {
        Name         string
        CurrentStatus string
    }
    if result.Next(l.ctx) {
        err = result.Record().Scan(&dbStatus.Name, &dbStatus.CurrentStatus)
        if err == nil && dbStatus.CurrentStatus == "online" {
            break
        }
    }
    result.Consume(l.ctx)
    time.Sleep(checkInterval)
}

// 检查是否超时
if time.Since(startTime) >= maxWaitTime {
    l.Error("数据库启动超时", req)
    // 超时后尝试删除未就绪的数据库
    waitSession.Run(l.ctx, fmt.Sprintf("drop database %s", graphName), nil)
    return &types.Response{
        Status:  false,
        Message: "数据库启动超时",
    }, nil
}

// 获取新的数据库会话来制图
cursession := l.svcCtx.Neo4jConn.NewSession(l.ctx, neo4j.SessionConfig{
    DatabaseName: graphName,
})
defer cursession.Close(l.ctx)
defer func() {
    if err != nil || !resp.Status {
        // 使用graphName而不是originid
        cursession.Run(l.ctx, fmt.Sprintf("drop database %s", graphName), nil)
    }
}()

for i := 0; i < len(path); i++ {
    if err := l.svcCtx.Generator.Generate(l.ctx, strconv.Itoa(int(ownerid)), path[i], nodeName, relationshipName, cursession); err != nil {
        l.Error("生成图失败", req, err.Error())
        return &types.Response{
            Status:  false,
            Message: "创建失败",
        }, nil
    }
}

额外注意事项

  • 调整等待时间参数:根据你的Neo4j服务器性能,可适当调整maxWaitTime和checkInterval的值,确保数据库有足够时间完成启动。
  • 错误处理:在等待过程中,如果遇到查询错误,不要直接退出,而是继续重试,避免因临时网络波动导致误判。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:07:22