数据库事务transaction

1.什么是事务?

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。--百度百科

例如,转账就是一个事务,它由两个操作组成:

  • 将款项从第一个账户划出。
  • 将款项存入第二个账户。

这两个操作要不全部成功,要不全部不成功。
如果第一个操作成功了,而第二个操作失败了,就需要回滚第一个操作。
从而保证数据一致性。

2.golang中对事务的支持

在golang 编程语言中,database/sql包提供了接口的支持。

实际上,一个事务就是一个对象,它占用一个到数据库的连接。一个事务中的所有操作,都保证在同一个连接上执行。

一个事务通过tx, err = db.Begin()创建,通过tx.Commit()tx.Rollback()关闭。
Tx会从连接池中获取一个连接,事务中所有操作都在这个连接上执行。

在事务中执行的操作,都要使用Tx变量,不要再使用db变量,db变量不属于事务范围,会使用不同的连接。

如果执行的多个语句,其中涉及修改连接状态,这时应该使用事务。

修改连接状态的情况有:

  • 创建临时表(仅对一个连接可见)
  • 修改变量,例如 SET @var := somevalue
  • 修改连接选项,例如 字符集 或 超时时间

以上任何操作,都需要绑定到连接。因此需要使用事务。

事务的基本操作包括:

开启事务

func (db *DB) Begin() (*Tx, error)

开启一个事务,隔离级别使用driver的默认事务级别。更多事务配置可以使用BeginTx

执行更新操作

func (tx *Tx) Exec(query string, args ...interface{}) (Result, error)

例如,update, insert。

提交

func (tx *Tx) Commit() error

回滚

func (tx *Tx) Rollback() error

下面举例说明具体使用方法。

例子

例子中,会执行两个update的sql,这两个操作放在一个事务中,保证要么同时更新成功,要么同时更新失败。

package main

import (
        "database/sql"
        "log"
        "time"

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

var DB *sql.DB
var dataBase = "root:Aa123456@tcp(192.168.0.101:3306)/?timeout=5s&readTimeout=6s"

func mysqlInit() {
        var err error
        DB, err = sql.Open("mysql", dataBase)
        if err != nil {
                log.Fatalln("open db fail:", err)
        }
}

func main() {
        mysqlInit()

        TryTransaction(DB)
}

func TryTransaction(db *sql.DB) (sql.Result, error) {
	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}

	sql := "update t set count=6 where id=1"
	res, err := tx.Exec(sql)
	if err != nil {
		if err2 := tx.Rollback(); err2 != nil {
			return res, fmt.Errorf("err:%s, err2:%s", err, err2)
		}
		return res, err
	}

	sql = "update t set count=10 where id=2"
	res, err = tx.Exec(sql)
	if err != nil {
		if err2 := tx.Rollback(); err2 != nil {
			return res, fmt.Errorf("err:%s, err2:%s", err, err2)
		}
		return res, err
	}

	if err := tx.Commit(); err != nil {
		return nil, err
	}

	return res, nil
}

3.参考

database/sql--Tx

Modifying Data and Using Transactions

Just try, don't shy.
原文地址:https://www.cnblogs.com/lanyangsh/p/14459006.html