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
相关产品推荐
相关产品推荐

