1. 程式人生 > >基於gin的golang web開發:使用資料庫事務

基於gin的golang web開發:使用資料庫事務

在前文介紹訪問資料庫時介紹了```github.com/jmoiron/sqlx```包,本文基於這個包使用資料庫事務。 ### defer 在使用資料庫事務之前,首先需要了解go語言的defer關鍵字。defer是go語言的延遲執行語句,defer後面的語句會被go進行延遲處理,在函式即將結束的時候,defer後面的語句將逆序執行。也就是說,先defer的語句最後執行。defer很像java或者C#中的finally語句。下面通過一個例子看一下defer。 ``` package main import "fmt" func main() { fmt.Println("defer 開始") defer fmt.Println(1) defer fmt.Println(2) defer fmt.Println(3) panic("測試 panic") fmt.Println("defer 結束") } ``` 程式碼執行結果: ``` defer 開始 3 2 1 panic: 測試 panic goroutine 1 [running]: main.main() /tests/gookokok/main.go:10 +0x1b8 Process finished with exit code 2 ``` 通過執行結果可以看到defer的逆序輸出。在之後又手動觸發了一個panic,影響了最後一行的輸出```defer 結束```,go在觸發panic時優先執行了defer,足以證明defer是非常安全的,所以defer也常常被用來互斥解鎖、關閉檔案或資料庫事務的處理。 ### 事務 sqlx使用事務和```database/sql```相比擴展出了MustBegin()、MustExec()等方法,這樣就不需要在程式碼中手動處理很多錯誤。MustBegin會在出現錯誤的時候觸發panic而不是返回錯誤,這樣就可以在程式碼的更上一層統一處理錯誤。 ```golang tx, err := db.Begin() err = tx.Exec(...) err = tx.Commit() tx := db.MustBegin() tx.MustExec(...) err = tx.Commit() ``` sqlx支援以上兩種開啟事務的方法。MustBegin返回sqlx.Tx,sqlx.Tx也提供了Select,Get之類的API,執行資料庫操作和使用sqlx.DB是一樣的。 以上程式碼執行```tx.MustExec(...)```如果報錯的話,程式碼將沒有機會執行到```tx.Commit()```,這樣資料庫連線會等到go進行垃圾回收的時候才能關閉,而且很高併發的話,可能會佔滿資料庫連線數,造成站點無法訪問的情況。 ```golang tx := db.MustBegin() defer tx.Rollback() tx.MustExec(...) err = tx.Commit() ``` 程式碼中加入```defer tx.Rollback()```就可以解決問題。通過前面的介紹已知defer是在方法即將結束時執行,哪怕是程式碼出現異常也不會影響資料庫連線。 文章出處:[基於gin的golang web開發:使用資料庫事務][source] [source]: https://www.huaface.com/arti