golang實現mysql數據庫事務的提交與回滾
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","[email protected]") 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","[email protected]") 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() }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。如有錯誤或未考慮完全的地方,望不吝賜教。
推薦閱讀:
- Go語言操作MySQL的知識總結
- Golang 數據庫操作(sqlx)和不定字段結果查詢
- golang db事務的統一封裝的實現
- SQL Server中的事務介紹
- Java面試題沖刺第十二天–數據庫(2)