Golang база данных / sql MYSQL 8 дБ. Несоответствие запросов - PullRequest
1 голос
/ 09 марта 2020

Обнаружено странное несоответствие при выборе строк из mysql 8.0.19 после некоторой транзакции с набором результатов (например, в mysqlworkbench путем редактирования некоторых строк).

(для справки по этой функции: 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

Но Golang db.Query(SQL) по-прежнему непрерывно возвращает:

105 admin
106 user1
107 user2
109 user3

Требуется ли db.Query(SQL) обязательство поддерживать согласованность с текущим состоянием базы данных? Потому что после того, как я добавил db.Begin() и db.Commit(), он начал работать последовательно. Не пробовал другие базы данных, не похоже на проблему с драйвером или проблему с копированием переменной. Это немного странно из JDB C. Автокоммит отключен.

Код:

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
}

1 Ответ

2 голосов
/ 10 марта 2020

Это примерно MySQL MV CC (см. 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...