Go基礎之 操作Mysql 三

2021-09-08 13:55:46 字數 2342 閱讀 9159

事務是資料庫的乙個非常重要的特性,尤其對於銀行,支付系統,等等。

database/sql提供了事務處理的功能。通過tx物件實現。db.begin會建立tx物件,後者的exec和query執行事務的資料庫操作,最後在tx的commit和rollback中完成資料庫事務的提交和回滾,同時釋放連線。

我們在之前查詢以及運算元據庫都是用的db物件,而事務則是使用另外乙個物件.

使用db.begin 方法可以建立tx物件,tx物件也可以對資料庫互動的query,exec方法

用法和我們之前操作基本一樣,但是需要在查詢或者操作完畢之後執行tx物件的commit提交或者rollback方法回滾。

一旦建立了tx物件,事務處理都依賴於tx物件,這個物件會從連線池中取出乙個空閒的連線,接下來的sql執行都基於這個連線,知道commit或者roolback呼叫之後,才會把這個連線釋放到連線池。

在事務處理的時候,不能使用db的查詢方法,當然你如果使用也能執行語句成功,但是這和你事務裡執行的操作將不是乙個事務,將不會接受commit和rollback的改變,如下面操作時:

tx,err :=db.begin()

db.exec()

tx.exec()

tx.commit()

上面這個偽**中,呼叫db.exec方法的時候,和tx執行exec方法時候是不同的,只有tx的會繫結到事務中,db則是額外的乙個連線,兩者不是同乙個事務。

建立tx物件的時候,會從連線池中取出連線,然後呼叫相關的exec方法的時候,連線仍然會繫結在該事務處理中。

事務的連線生命週期從beigin函式呼叫起,直到commit和rollback函式的呼叫結束。

rows, _ := db.query("select id from user") 

for rows.next()

呼叫了query方法之後,在next方法中取結果的時候,rows是維護了乙個連線,再次呼叫queryrow的時候,db會再從連線池取出乙個新的連線。rows和db的連線兩者可以並存,並且相互不影響。

但是如果邏輯在事務處理中會失效,如下**:

rows, _ := tx.query("select id from user")

for rows.next()

tx執行了query方法後,連線轉移到rows上,在next方法中,tx.queryrow將嘗試獲取該連線進行資料庫操作。因為還沒有呼叫rows.close,因此底層的連線屬於busy狀態,tx是無法再進行查詢的。

通過下面乙個完整的例子就行更好的理解:

func dosomething()

func cleartransaction(tx *sql.tx)

}func main()

defer db.close()

tx, err :=db.begin()

if err !=nil

defer cleartransaction(tx)

rs, err := tx.exec("update user set gold=50 where real_name='vanyarpy'")

if err !=nil

rowaffected, err :=rs.rowsaffected()

if err !=nil

fmt.println(rowaffected)

rs, err = tx.exec("update user set gold=150 where real_name='noldorpy'")

if err !=nil

rowaffected, err =rs.rowsaffected()

if err !=nil

fmt.println(rowaffected)

dosomething()

if err := tx.commit(); err !=nil

}

這裡定義了乙個cleartransaction(tx)函式,該函式會執行rollback操作。因為我們事務處理過程中,任何乙個錯誤都會導致main函式退出,因此在main函式退出執行defer的rollback操作,回滾事務和釋放連線。

如果不新增defer,只在最後commit後check錯誤err後再rollback,那麼當dosomething發生異常的時候,函式就退出了,此時還沒有執行到tx.commit。這樣就導致事務的連線沒有關閉,事務也沒有回滾。

tx事務環境中,只有乙個資料庫連線,事務內的eexc都是依次執行的,事務中也可以使用db進行查詢,但是db查詢的過程會新建連線,這個連線的操作不屬於該事務。

GO基礎之檔案操作

func main else 檔案路徑 1 判斷是否是絕對路徑filepath.isabs 2 獲取相對路徑filepath.rel 3 獲取絕對路徑filepath.abs 4 拼接路徑path.join 檔案操作 1.建立資料夾,如果資料夾存在,建立失敗 2.建立檔案 如果檔案存在,會覆蓋 3....

Go 語言操作 MySQL 之 CURD 操作

mysql 是目前開發中最常見的關係型資料庫,使用 go 語言進行操控資料庫需要使用 go 自帶database sql和驅動go sql driver mysql來實現,建立好 go 專案,需要引用驅動依賴 go get u github.com go sql driver mysql使用 mys...

Go 語言操作 MySQL 之 預處理

預處理是 mysql 為了防止客戶端頻繁請求的一種技術,是對相同處理語句進行預先載入在 mysql 中,將操作變數資料用佔位符來代替,減少對 mysql 的頻繁請求,使得伺服器高效執行。在這裡客戶端並不是前台後台之間的 c s 架構,而是後台程式對資料庫伺服器進行操作的 c s 架構,這樣就可以簡要...