downing1988 2017-04-23 09:28
浏览 112
已采纳

Statement.Close是否会影响golang中mysql的线程安全LAST_INSERT_ID?

I'm using go to insert a new user into the mysql database. Before inserting the user I save some kind of "log-message" in the msg table. Both tables (msgand user) have auto-increment. In order to receive the id chosen by auto-increment I use mysql's LAST_INSERT_ID() function. This should be thread-safe as pointed out in lots of other discussions on stack overflow, because it's bound to a single connection.

I asked myself if stmt.Close() after every stmt.Exec() will change mysql's behavior (specially thread-safeness) in any way?

stmt, _ := db.Prepare("INSERT INTO msg (message) VALUES(?)")
stmt.Exec(msg)
stmt.Close()

stmt, _ = db.Prepare("SELECT LAST_INSERT_ID()")
stmt.QueryRow().Scan(&msgid)
stmt.Close()

stmt, _ = db.Prepare("INSERT INTO user (msg_id) VALUES(?)")
stmt.Exec(msgid)
stmt.Close()

stmt, _ = db.Prepare("SELECT LAST_INSERT_ID()")
stmt.QueryRow().Scan(&id)
stmt.Close()
  • 写回答

1条回答 默认 最新

  • douzhenzu0247 2017-04-23 09:34
    关注

    Closing the statement, as you're doing, does not close the database connection. The database connection is what's important for LAST_INSERT_ID. Unless you call db.Close(), which closes the underlying connection, your connection remains open.

    However, db is a pool of connections, so there is no guarantee that you'll get the same connection on subsequent queries, regardless of closing the connection, unless you use a transaction.

    So in summary, you should do this (adding error handling, of course)

    tx, _ := db.Begin()
    
    stmt, _ := tx.Prepare("INSERT INTO msg (message) VALUES(?)")
    stmt.Exec(msg)
    stmt.Close()
    
    stmt, _ = tx.Prepare("SELECT LAST_INSERT_ID()")
    stmt.QueryRow().Scan(&msgid)
    stmt.Close()
    
    _ = tx.Commit()
    

    However, note that a better way to do this is with Result.LastInsertId:

    stmt, _ := tx.Prepare("INSERT INTO msg (message) VALUES(?)")
    res, _ := stmt.Exec(msg)
    stmt.Close()
    
    msgid := res.LastInsertId()
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R
  • ¥15 在线请求openmv与pixhawk 实现实时目标跟踪的具体通讯方法
  • ¥15 八路抢答器设计出现故障
  • ¥15 opencv 无法读取视频
  • ¥15 按键修改电子时钟,C51单片机
  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档