golang panic: sql: Register called twice for driver mysql

背景

在工作中,为了简洁和统一,准备将项目B作为基础库引用到我做的项目A中,项目A和B都引用了database/sql以及github.com/go-sql-driver/mysql。做了一系列代码调整后,项目A编译通过,但是运行的时候报错:

golang panic: sql: Register called twice for driver mysql

调查过程

在database/sql/sql.go中找到了这个报错信息,drivers是个map,如果相同的name出现两次就会触发这个错误信息,也就是说Register函数以相同的name作为参数被调用了两次。

func Register(name string, driver driver.Driver) {
	driversMu.Lock()
	defer driversMu.Unlock()
	if driver == nil {
		panic("sql: Register driver is nil")
	}
	if _, dup := drivers[name]; dup {
		panic("sql: Register called twice for driver " + name)
	}
	drivers[name] = driver
}

在go-sql-driver/mysql/driver.go中有个init函数调用了Register函数,对于合并后的项目A和B来说,意味着这个init函数被调用了两次。由于golang中的init函数只会被自动调用一次,虽然项目A和B都import了mysql这个driver,是不应该导致两次init的两次调用的。

func init() {
	sql.Register("mysql", &MySQLDriver{})
}

再次检查了项目A和项目B的结构,发现项目B用到了vendor,而且vendor中包括了go-sql-driver/mysql,而项目A用的是golang安装路径下pkg中的mysql driver。至此,怀疑是因为项目A和B引用了不同路径上的mysql driver导致触发了这个错误信息。

解决

临时把go-sql-driver/mysql从项目B的vendor中移除出去后,项目A编译通过并且运行正常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值