当前位置 博文首页 > golang实现mysql数据库事务的提交与回滚

    golang实现mysql数据库事务的提交与回滚

    作者:wade3015 时间:2021-06-02 18:09

    MySQL 事务主要用于处理操作量大,复杂度高的数据。在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

    事务用来管理 insert,update,delete 语句,事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

    一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

    本文主要介绍golang实现MySQL数据库事物的提交与回滚

    用到的库有:

    "github.com/jmoiron/sqlx"
    _ "github.com/go-sql-driver/mysql"

    事务(Transactions)

    事务操作是通过三个方法实现:

    Begin():开启事务

    Commit():提交事务(执行sql)

    Rollback():回滚

    举例:

    在事物里操作MySQL任意一步操作出错,都需要Rollback()回滚。

    package main 
    import (
     "fmt"
     "github.com/alecthomas/log4go"
     _ "github.com/go-sql-driver/mysql"
     "github.com/jmoiron/sqlx"
    )
     
    var Db *sqlx.DB 
    func init()  {
     db,err:=sqlx.Open("mysql","TigerwolfC:123456@tcp(127.0.0.1:3306)/test?charset=utf8")
     if err != nil {
      fmt.Println("open mysql failed,", err)
      return
     }
     Db = db
    }
     
    func main()  {
     mysqlTest()
    } 
     
    func mysqlTest() error{
     tx, err := Db.Begin()
     if err != nil {
      log4go.Error("open mysql database fail", err)
      return err
     }
     
     result, err := tx.Exec("INSERT INTO userinfo (username, password,department,email) VALUES (?, ?,?,?)","cici","33333","it","TigerwolfC@163.com")
     if err != nil{
      fmt.Println("insert failed,error: ", err)
      tx.Rollback()
      return err
     }
     id,_ := result.LastInsertId()
     fmt.Println("insert id is :",id)
     _, err = tx.Exec("update userinfo set department = ? where username = ?","cekong","hahah")
     if err != nil{
      fmt.Println("update failed error:",err)
      tx.Rollback()
      return err
     } else {
      fmt.Println("update success!")
     }
     _, err = tx.Exec("delete from userinfo where username = ? ", "weiwei")
     if err != nil{
      fmt.Println("delete error:",err)
      tx.Rollback()
      return err
     }else{
      fmt.Println("delete success")
     }
     return tx.Commit()
    }

    当然也可以用defer tx.Rollback(),在程序退出前回滚。

    func mysqlTest() error{
     tx, err := Db.Begin()
     if err != nil {
      log4go.Error("open mysql database fail", err)
     }
     defer tx.Rollback()
     
     result, err := tx.Exec("INSERT INTO userinfo (username, password,department,email) VALUES (?, ?,?,?)","cici","33333","it","TigerwolfC@163.com")
     if err != nil{
      fmt.Println("insert failed,error: ", err)
      return err
     }
     id,_ := result.LastInsertId()
     fmt.Println("insert id is :",id)
     _, err = tx.Exec("update userinfo set department = ? where username = ?","cekong","hahah")
     if err != nil{
      fmt.Println("update failed error:",err)
      return err
     } else {
      fmt.Println("update success!")
     }
     _, err = tx.Exec("delete from userinfo where username = ? ", "weiwei")
     if err != nil{
      fmt.Println("delete error:",err)
      return err
     }else{
      fmt.Println("delete success")
     }
     return tx.Commit()
    }

    补充:数据库事务处理(go,mysql)

    看代码吧~

    //数据库连接池
    var db *sql.DB
    //初始化数据库
    func initDB() (err error){
    	fmt.Println("学习数据库")
    	dsn := "usename:password@tcp(127.0.0.1:3306)/dataname"
    	db, err = sql.Open("mysql",dsn)
    	if err!=nil {
    		fmt.Println("打开数据库失败 err:",err,".dsn:",dsn)
    		return
    	}
    	err = db.Ping()
    	if err!=nil {
    		fmt.Println("open failed err:",err)
    		return
    	}
    	fmt.Println("连接数据库成功")
     
    	//最大连接数
    	db.SetMaxOpenConns(10)
    	//设置连接池中的最大闲置连接数
    	db.SetMaxIdleConns(10)
    	return
    }
     
    func trans()  {
    	tx, err := db.Begin()
    	if err!=nil {
    		fmt.Println("事务开启失败, err:",err)
    		return
    	}
    	sqlStr1 := "update student set age=age-2 where id=1;"
    	sqlStr2 := "update student set age=age+2 where id=3;"
    	_, err = tx.Exec(sqlStr1)
    	if err!=nil {
    		fmt.Println("修改失败, err",err,",sqlStr1:",sqlStr1)
    		tx.Rollback()
    		return
    	}
     
    	_, err = tx.Exec(sqlStr2)
    	if err!=nil {
    		fmt.Println("修改失败, err",err,",sqlStr2:",sqlStr2)
    		tx.Rollback()
    		return
    	}
     
    	fmt.Println("执行成功")
    	//提交事务
    	tx.Commit()
    }
    func main() {
    	fmt.Println("mysql 002.事务处理")
    	initDB()
    	trans() 
    }

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持站长博客。如有错误或未考虑完全的地方,望不吝赐教。

    js
    下一篇:没有了