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ù)是必須滿足4個(gè)條件(ACID)::原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨(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)文章
go語(yǔ)言實(shí)現(xiàn)銀行卡號(hào)Luhn校驗(yàn)
這篇文章主要為大家介紹了go語(yǔ)言Luhn校驗(yàn)測(cè)試銀行卡號(hào)碼的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
GO語(yǔ)言中Chan實(shí)現(xiàn)原理的示例詳解
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中Chan實(shí)現(xiàn)原理的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考一下2023-02-02
golang使用sync.singleflight解決熱點(diǎn)緩存穿透問(wèn)題
在go的sync包中,有一個(gè)singleflight包,里面有一個(gè)?singleflight.go文件,代碼加注釋,一共200行出頭,通過(guò)?singleflight可以很容易實(shí)現(xiàn)緩存和去重的效果,避免重復(fù)計(jì)算,接下來(lái)我們就給大家詳細(xì)介紹一下sync.singleflight如何解決熱點(diǎn)緩存穿透問(wèn)題2023-07-07
goland中導(dǎo)包報(bào)紅和go mod問(wèn)題
這篇文章主要介紹了goland中導(dǎo)包報(bào)紅和go mod問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
Golang極簡(jiǎn)入門(mén)教程(二):方法和接口
這篇文章主要介紹了Golang極簡(jiǎn)入門(mén)教程(二):方法和接口,本文同時(shí)講解了錯(cuò)誤、匿名域等內(nèi)容,需要的朋友可以參考下2014-10-10
Golang通道阻塞情況與通道無(wú)阻塞實(shí)現(xiàn)小結(jié)
本文主要介紹了Golang通道阻塞情況與通道無(wú)阻塞實(shí)現(xiàn)小結(jié),詳細(xì)解析了通道的類型、操作方法以及垃圾回收機(jī)制,從基礎(chǔ)概念到高級(jí)應(yīng)用,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
關(guān)于Golang中for-loop與goroutine的問(wèn)題詳解
這篇文章主要給大家介紹了關(guān)于Golang中for-loop與goroutine問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用golang具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09

