最近零碎学习了一点sql的连接方面的知识。在之前,要么数据库已关闭,要么连接数超出最大数,纠结。

1.open后是否要close?实际上不用close,在调用的function里,具体到db.Query后,用defer rows.Close()就行了。

2. 而QueryRow后面不需要close。

3.begin()是事务准备。var tx *sql.Tx和defer tx.Rollback()​​

也就是说Ping和Exec方法在调用完之后,会自动释放连接。把代码中所有不需要返回值的语句改成由Exce方法执行,go run 一下,ok,连接数终于正常了! 

        问题是解决了,总起来以后要注意一下的东西: 


  • 程序连接数据库会有连接泄漏的情况,需要及时释放连接 
  • Go sql包中的Query和QueryRow(@qgymje 在评论中提到,QueryRow通过调用Scan方法,会自动关闭连接的)两个方法的连接不会自动释放连接,只有在遍历完结果或者调用close方法才会关闭连接 
  • Go sql中的Ping和Exec方法在调用结束以后就会自动释放连接 
  • 忽略了函数的某个返回值不代表这个值就不存在了,如果该返回值需要close才会释放资源,直接忽略了就会导致资源的泄漏。 
  • 有close方法的变量,在使用后要及时调用该方法,释放资源

golang Mysql -- Tx

atabase/sql提供了事务处理的功能。通过Tx对象实现。db.Begin会创建tx对象,后者的Exec和Query执行事务的数据库操作,最后在tx的Commit和Rollback中完成数据库事务的提交和回滚,同时释放连接。

tx事务环境中,只有一个数据库连接,事务内的Eexc都是依次执行的,事务中也可以使用db进行查询,但是db查询的过程会新建连接,这个连接的操作不属于该事务。


tx := db.Begin()
tx.Rollback() // 回滚
tx.Commit()
//然后通过tx操作Exec, Query, QueryRow and Prepare 方法,流程和上面一样。示例
tx, err := db.Begin()
stmt, err := tx.Prepare(`UPDATE student SET age=? WHERE id=?`)
_, err = stmt.Exec(18, 5)
if err != nil {
tx.Rollback()
panic(err)
}
err = tx.Commit()
if err != nil {
tx.Rollback()
panic(err)
}


导入
"database/sql"
"github.com/go-sql-driver/mysql"
类包

Tx,_ := connectMysql.Begin()
stm,_ := Tx.Preapare("insert into test values(?,null)")
result,_ := stm.Exec('123')
error := Tx.Commit()或者error := Tx.Rollback()