cpp

MySQL. Транзакции

Очень часто несколько запросов выполняются последовательно. Например, при совершении покупки деньги списываются со счета клиента и сразу добавляются на счет магазина. Если во время добавления денег на счет магазина произойдет ошибка, то деньги будут списаны со счета клиента, но не попадут на счет магазина. Чтобы гарантировать успешное выполнение группы запросов, используется механизм транзакций.

Обратите внимание!

Запуск транзакции осуществляется методом Begin(). Формат метода:

(*sql.DB).Begin() (*sql.Tx, error)

Через первое возвращаемое значение доступен указатель на структуру sql.Tx. Через второе возвращаемое значение доступен объект ошибки или значение nil, если операция выполнена успешно. После запуска транзакции группа запросов выполняется как единое целое.

Структура sql.Tx содержит следующие основные методы:

  • Commit() — применяет запросы. Метод возвращает объект ошибки или значение nil, если операция выполнена успешно. Формат метода:
(*sql.Tx).Commit() error
  • Rollback() — позволяет отменить все изменения в рамках транзакции. Вызов метода будет проигнорирован, если ранее был вызван метод Commit(). Метод возвращает объект ошибки или значение nil, если операция выполнена успешно. Формат метода:
(*sql.Tx).Rollback() error

Выполнить запросы к базе данных позволяют уже знакомые нам методы Exec(), Query(), QueryRow() и Prepare(), только они вызываются через объект структуры sql.Tx. Форматы методов:

(*sql.Tx).Exec(query string, args ...interface{}) (sql.Result, error)
(*sql.Tx).Query(query string, args ...interface{}) (*sql.Rows, error)
(*sql.Tx).QueryRow(query string, args ...interface{}) *sql.Row
(*sql.Tx).Prepare(query string) (*sql.Stmt, error)

Если уже существует подготовленный запрос, то его объект можно передать в метод Stmt(). Формат метода:

(*sql.Tx).Stmt(stmt *sql.Stmt) *sql.Stmt

Пример выполнения запросов в рамках транзакции приведен в листинге 16.10.

Листинг 16.10. Транзакции

package main

import (
   "database/sql"
   "fmt"
   "os"

   _ "github.com/go-sql-driver/mysql"
)

func main() {
   db, err := sql.Open("mysql", "root:@/godb")
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   defer db.Close()
   tx, err := db.Begin() // Запуск транзакции
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   defer tx.Rollback() // Отменяем запросы
   _, err = tx.Exec("INSERT INTO `user` (`email`, `passw`)" +
                    " VALUES ('user3@mail.ru', 'пароль')")
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   // Выполняем еще какие-либо связанные запросы
   if err = tx.Commit(); err != nil { // Применяем запросы
      fmt.Fprintln(os.Stderr, err)
      return
   }
   fmt.Println("Запросы успешно выполнены")
}

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp