在结果集上进行一些事务后(例如在mysqlworkbench上编辑一些行(,从mysql 8.0.19中选择行时发现了一个奇怪的不一致。
(此函数用于参考:https://golang.org/pkg/database/sql/#DB.Query)
换句话说,db.Query(SQL)
返回我的结果集的旧状态(在编辑和提交之前(。
编辑前的MYSQL行:
105 admin
106 user1
107 user2
109 user3
编辑后的MYSQL行:
105 admin
106 user11
107 user22
109 user33
但Golangdb.Query(SQL)
仍连续返回:
105 admin
106 user1
107 user2
109 user3
db.Query(SQL)
是否需要提交以保持与当前数据库状态的一致性?因为在我添加了db.Begin()
和db.Commit()
之后,它开始稳定地工作。没有尝试过其他数据库,看起来不像是驱动程序问题或变量复制问题。来自JDBC有点奇怪。已禁用自动提交。
代码:
func FindAll(d *sql.DB) ([]*usermodel.User, error) {
const SQL = `SELECT * FROM users t ORDER BY 1`
//tx, _ := d.Begin()
rows, err := d.Query(SQL)
if err != nil {
return nil, err
}
defer func() {
err := rows.Close()
if err != nil {
log.Fatalln(err)
}
}()
l := make([]*usermodel.User, 0)
for rows.Next() {
t := usermodel.NewUser()
if err = rows.Scan(&t.UserId, &t.Username, &t.FullName, &t.PasswordHash, &t.Email, &t.ExpireDate,
&t.LastAuthDate, &t.StateId, &t.CreatedAt, &t.UpdatedAt); err != nil {
return nil, err
}
l = append(l, t)
}
if err = rows.Err(); err != nil {
return nil, err
}
//_ = tx.Commit()
return l, nil
}
这纯粹是关于MySQL MVCC的(请参阅https://dev.mysql.com/doc/refman/8.0/en/innodb-multi-versioning.html和https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html)而不是Go/DB驱动程序。
简而言之,如果您启动一个事务,读取一些数据,然后另一个事务对其进行更改并提交,您可能会看到结果,也可能不会看到结果,这取决于MySQL服务器上设置的事务隔离级别。