Когда программа Golang завершается во время выполнения транзакции базы данных, может ли она откатиться? - PullRequest
0 голосов
/ 04 декабря 2018

Предполагается, что база данных, совместимая с MariaDB (AWS Aurora RDS) с настройками по умолчанию, которая включает с включенной автоматической фиксацией , если лямбда-функция была прервана через три секунды , выполнив транзакцию, которая занимает более пять секунд , например

  tx, err := h.db.Begin()
  if err != nil {
      log.WithError(err).Error("failed to start transaction")
  }
  res, execErr := tx.Exec(fmt.Sprintf("UPDATE testtable SET val = %d WHERE id = 1; SELECT SLEEP(5.5);", time.Now().Unix()))
  if execErr != nil {
      log.WithError(err).Error("rolling back")
      err = tx.Rollback()
      if err != nil {
          log.WithError(err).Error("failed to roll back")
      }
  }
  if err := tx.Commit(); err != nil {
      log.WithError(err).Error("failed to commit")
  }

Каким будет результат?Транзакция не была совершена?

Я использую Go MySQL Driver v1.3.0-84-g6be42e0, кстати.Я также сделал видео, показывающее мои результаты , но мне интересно, правильно ли это, так как я не понимаю, как драйвер мог выполнить откат .

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

Если вы используете таблицы InnoDB, прочитайте это из https://dev.mysql.com/doc/internals/en/transactions-life-cycle.html:

Когда соединение закрыто, текущая обычная транзакция, если она есть, откатывается.

Это работает так же с клиентом Go, клиентом Java, клиентом PHP или любым другим клиентом.

Если вы используете таблицы MyISAM, отката не будет.Если в данный момент выполняется обновление SQL, оно может обновить некоторое подмножество строк и оставить остальные без изменений.В итоге вы получите таблицу в несогласованном состоянии.Поведение ACID с нетранзакционными таблицами отсутствует. Вот почему вы не должны использовать MyISAM.

0 голосов
/ 04 декабря 2018

Транзакция SQL не фиксируется.То, что я считаю, происходит с таймаутом <= 5s: </p>

  1. BEGINs транзакция
  2. Синхронно выполняет SQL
  3. MySQLd обнаруживает клиента, отключенного через TCP FIN
  4. MySQLd автоматически откатывается, так как не видит фиксации

Ответ на твит от одного из драйверов Golang MySQL сопровождающих:

mysqld получает пакет TCP FIN, когда клиент Go завершается.
Несмотря на то, что клиент Go выходит нечистым образом, ОС (ядро Linux и т. д.) отправляет TCP FIN или TCP RST.Так что mysqld может знать, что клиент ушел. - ИНАДА Наоки (@methane) 4 декабря 2018
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...