Mysql 事务锁等待时间超时
一 问题描述
Lock wait timeout exceeded; try restarting transaction
二 处理过程
首先假如在生产中遇到这个问题,我们必然是先找到这个循环等待的线程,给他kill了,如下
然后kill掉957和958
三 系统调节
一般mysql的inodb有个默认事物等待时间,超过这个时间他会自动结束且抛出异常,参数为innodb_lock_wait_timeout,默认50s,修改它即可
四 代码链路追踪
分析出代码是在同一个表的同一行进行第二次updt操作的时候锁住了,然后也查阅相关资料,发现有的coder说这种情况会发生锁死。然后本人做了个测试
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" "time" ) var MysqlDb *sql.DB var MysqlDbErr error // 初始化链接 //func InitDb() { func init() { m_user := "wbw" m_pd := "123456" m_host := "127.0.0.1" m_pt := "3306" m_db := "test_local" dbDSN := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s", m_user, m_pd, m_host, m_pt, m_db, "utf8") // 打开连接失败 MysqlDb, MysqlDbErr = sql.Open("mysql", dbDSN) //defer MysqlDb.Close(); if MysqlDbErr != nil { panic("数据源配置不正确: " + MysqlDbErr.Error()) } // 最大连接数 MysqlDb.SetMaxOpenConns(100) // 闲置连接数 MysqlDb.SetMaxIdleConns(20) // 最大连接周期 MysqlDb.SetConnMaxLifetime((30)*time.Second) if MysqlDbErr = MysqlDb.Ping(); nil != MysqlDbErr { panic("数据库链接失败: " + MysqlDbErr.Error()) } } func main(){ //ifupdt,err := UpdtCarrierRemark("asd","hah2") ifupdt,err := UpdtCarrierRemarkTrx("asd","hatt") fmt.Println(ifupdt,err) } func UpdtCarrierRemark(asn_id string,remark string) (bool,error){ _,errs := MysqlDb.Exec("update ls_wms_asn set " + "remark=? where (asn_id=?) ",remark,asn_id) if errs != nil{ fmt.Println(errs) return false,errs } return true,nil } func UpdtCarrierRemarkTrx(asn_id string,remark string) (bool,error){ tx, _ := MysqlDb.Begin() _,errs := tx.Exec("update ls_wms_asn set " + "remark=? where (asn_id=?) ",remark,asn_id) if errs != nil{ fmt.Println(errs) tx.Rollback() return false,errs } _,errs2 := tx.Exec("update ls_wms_asn set " + "remark_ct=201 where (asn_id=?) ",asn_id) if errs2 != nil{ fmt.Println(errs2) tx.Rollback() return false,errs2 } tx.Commit() return true,nil }
做了验证后发现并没有发生锁死的情况,然后猜测可能是并发不够,所以专门又用ab测试了1s钟100次的并发,也未发生锁死。
所以暂时排除此种原因
五 小失误导致
原来我代码中用的是MysqlDb.Exec,而非tx.Exec
当我们开启事务tx, _ := MysqlDb.Begin()后,对db的操作都应该用tx来完成,而非常规的DB单例变量。
虽然原因找到了,是个简单失误,但是能够简单回顾下事物锁死的处理过程,也算小有收获