golang實(shí)現(xiàn)mysql數(shù)據(jù)庫(kù)事務(wù)的提交與回滾
MySQL 事務(wù)主要用于處理操作量大,復(fù)雜度高的數(shù)據(jù)。在 MySQL 中只有使用了 Innodb 數(shù)據(jù)庫(kù)引擎的數(shù)據(jù)庫(kù)或表才支持事務(wù)。
事務(wù)用來(lái)管理 insert,update,delete 語(yǔ)句,事務(wù)處理可以用來(lái)維護(hù)數(shù)據(jù)庫(kù)的完整性,保證成批的 SQL 語(yǔ)句要么全部執(zhí)行,要么全部不執(zhí)行。
一般來(lái)說(shuō),事務(wù)是必須滿(mǎn)足4個(gè)條件(ACID)::原子性(Atomicity,或稱(chēng)不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱(chēng)獨(dú)立性)、持久性(Durability)。
本文主要介紹golang實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)事物的提交與回滾
用到的庫(kù)有:
"github.com/jmoiron/sqlx" _ "github.com/go-sql-driver/mysql"
事務(wù)(Transactions)
事務(wù)操作是通過(guò)三個(gè)方法實(shí)現(xiàn):
Begin():開(kāi)啟事務(wù)
Commit():提交事務(wù)(執(zhí)行sql)
Rollback():回滾
舉例:
在事物里操作MySQL任意一步操作出錯(cuò),都需要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() }
當(dāng)然也可以用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() }
補(bǔ)充:數(shù)據(jù)庫(kù)事務(wù)處理(go,mysql)
看代碼吧~
//數(shù)據(jù)庫(kù)連接池 var db *sql.DB //初始化數(shù)據(jù)庫(kù) func initDB() (err error){ fmt.Println("學(xué)習(xí)數(shù)據(jù)庫(kù)") dsn := "usename:password@tcp(127.0.0.1:3306)/dataname" db, err = sql.Open("mysql",dsn) if err!=nil { fmt.Println("打開(kāi)數(shù)據(jù)庫(kù)失敗 err:",err,".dsn:",dsn) return } err = db.Ping() if err!=nil { fmt.Println("open failed err:",err) return } fmt.Println("連接數(shù)據(jù)庫(kù)成功") //最大連接數(shù) db.SetMaxOpenConns(10) //設(shè)置連接池中的最大閑置連接數(shù) db.SetMaxIdleConns(10) return } func trans() { tx, err := db.Begin() if err!=nil { fmt.Println("事務(wù)開(kāi)啟失敗, 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("執(zhí)行成功") //提交事務(wù) tx.Commit() } func main() { fmt.Println("mysql 002.事務(wù)處理") initDB() trans() }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Gin golang web開(kāi)發(fā)模型綁定實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10golang框架中跨服務(wù)的最佳通信協(xié)議和工具
在 go 框架中實(shí)現(xiàn)跨服務(wù)通信的最佳實(shí)踐包括使用 grpc(適用于低延遲高吞吐量)、http 客戶(hù)端(適用于 restful api)和消息隊(duì)列(適用于異步解耦通信),在選擇通信方式時(shí),應(yīng)考慮服務(wù)交互模式、性能要求和部署環(huán)境等因素2024-06-06Golang實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能
這篇文章主要為大家詳細(xì)介紹了Golang實(shí)現(xiàn)斷點(diǎn)續(xù)傳、復(fù)制文件功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07golang簡(jiǎn)單獲取上傳文件大小的實(shí)現(xiàn)代碼
這篇文章主要介紹了golang簡(jiǎn)單獲取上傳文件大小的方法,涉及Go語(yǔ)言文件傳輸及文件屬性操作的相關(guān)技巧,需要的朋友可以參考下2016-07-07Go語(yǔ)言排序算法之插入排序與生成隨機(jī)數(shù)詳解
從這篇文章開(kāi)始將帶領(lǐng)大家學(xué)習(xí)Go語(yǔ)言的經(jīng)典排序算法,比如插入排序、選擇排序、冒泡排序、希爾排序、歸并排序、堆排序和快排,二分搜索,外部排序和MapReduce等,本文將先詳細(xì)介紹插入排序,并給大家分享了go語(yǔ)言生成隨機(jī)數(shù)的方法,下面來(lái)一起看看吧。2017-11-11Go語(yǔ)言利用接口實(shí)現(xiàn)鏈表插入功能詳解
這篇文章主要為大家介紹了Go語(yǔ)言中的接口,以及如何利用接口實(shí)現(xiàn)鏈表插入功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-04-04Golang處理parquet文件實(shí)戰(zhàn)指南
這篇文章主要給大家介紹了關(guān)于Golang處理parquet文件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Golang具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-03-03Go 標(biāo)準(zhǔn)庫(kù)增加metrics指標(biāo)探討分析
go中有一個(gè)神奇的標(biāo)準(zhǔn)庫(kù) runtime/metrics,提供了一系列預(yù)定義好的 Go 自身的相關(guān)指標(biāo),如果沒(méi)有編寫(xiě)過(guò)基礎(chǔ)監(jiān)控庫(kù)或者關(guān)注的比較少的朋友可能會(huì)沒(méi)接觸到這類(lèi)指標(biāo),本文展開(kāi)現(xiàn)有metrics 指標(biāo),并結(jié)合現(xiàn)有的社區(qū)討論一起看看還有沒(méi)有必要增加更多的標(biāo)準(zhǔn)庫(kù)指標(biāo)2023-10-10