使用Go操作MySQL时UPDATE/DELETE报bad connection错误求助
问题排查与解决:Go+MySQL CRUD中UPDATE/DELETE报invalid connection错误
一、先修复代码中的明显错误
1. DELETE操作参数不匹配
你的DELETE语句仅需1个id参数,但代码中传入了category.Name, category.Id两个参数,参数数量与SQL占位符不匹配,会直接导致执行失败,进而触发连接类错误提示。修改后的DELETE代码:
func (repository *CategoryRepositoryImpl) Delete(ctx context.Context, tx *sql.Tx, category domain.Category) { SQL := "delete from category where id = ?" // 仅传入id参数,移除多余的category.Name _, err := tx.ExecContext(ctx, SQL, category.Id) helper.PanicIfError(err) }
2. 连接池配置错误
在NewDB()函数中,你连续两次调用了db.SetMaxIdleConns,第二个调用应为SetMaxOpenConns(用于设置最大打开的数据库连接数),否则连接池的最大打开连接数会沿用默认值,与空闲连接数配置冲突,导致连接管理混乱。同时建议添加db.Ping()初始化时验证连接有效性:
func NewDB() *sql.DB { db, err := sql.Open("mysql", "MY_USERNAME:MY_PASSWORD@tcp(localhost:3306)/go_restful_api") helper.PanicIfError(err) db.SetMaxIdleConns(5) // 修正:将SetMaxIdleConns改为SetMaxOpenConns db.SetMaxOpenConns(20) db.SetConnMaxLifetime(60 * time.Minute) db.SetConnMaxIdleTime(10 * time.Minute) // 初始化时检测连接是否正常 if err := db.Ping(); err != nil { helper.PanicIfError(err) } return db }
二、深层排查方向(若修复后仍报错)
- MySQL连接超时参数:检查MySQL的
wait_timeout和interactive_timeout配置,确保ConnMaxLifetime的值小于这两个参数(MySQL默认值为8小时,你设置的60分钟是合理的,但如果服务器端参数被修改,需同步调整)。可通过SHOW VARIABLES LIKE '%timeout%';查看参数值。 - 事务有效性检查:确认使用的
tx事务对象未被提前提交、回滚或复用,无效的事务对象会导致连接错误。 - 驱动版本升级:你使用的
github.com/go-sql-driver/mysql v1.6.0版本较旧,可升级至最新稳定版(如v1.7.0+),修复已知的连接池相关bug。
三、修复后验证重点
- 确认UPDATE语句的参数数量与占位符完全匹配(你的UPDATE代码参数逻辑是正确的)
- 确保事务流程完整:开启事务→执行操作→提交/回滚事务,无遗漏步骤
内容的提问来源于stack exchange,提问作者ramadoiranedar
相关产品推荐
相关产品推荐

