最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言結(jié)合GORM實(shí)現(xiàn)數(shù)據(jù)庫(kù)事務(wù)處理的示例代碼

 更新時(shí)間:2025年08月20日 10:03:22   作者:程序員愛釣魚  
這篇文章主要為大家詳細(xì)介紹了Go語言結(jié)合GORM實(shí)現(xiàn)數(shù)據(jù)庫(kù)事務(wù)處理的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

在實(shí)際業(yè)務(wù)中,很多操作需要保證 要么全部成功,要么全部失敗,否則可能造成數(shù)據(jù)不一致。比如:

  • 用戶轉(zhuǎn)賬(A 賬戶扣款,B 賬戶加款)
  • 下單支付(生成訂單、扣減庫(kù)存、記錄支付)

這種場(chǎng)景就需要用到 事務(wù)(Transaction)

本文將帶你使用 Go 語言 + GORM 實(shí)現(xiàn)數(shù)據(jù)庫(kù)事務(wù)處理。

一、事務(wù)的基本概念

事務(wù)(Transaction)是數(shù)據(jù)庫(kù)中一組不可分割的操作單元,具有四大特性(ACID):

  • 原子性(Atomicity):事務(wù)中的所有操作要么全部成功,要么全部失敗。
  • 一致性(Consistency):事務(wù)執(zhí)行前后,數(shù)據(jù)必須保持一致。
  • 隔離性(Isolation):多個(gè)事務(wù)之間相互獨(dú)立,互不干擾。
  • 持久性(Durability):事務(wù)一旦提交,結(jié)果會(huì)永久保存。

二、GORM 事務(wù)處理方式

GORM 提供了三種事務(wù)使用方式:

  • 手動(dòng)開啟、提交、回滾
  • db.Transaction() 包裹函數(shù)(推薦)
  • 嵌套事務(wù)(SavePoint / RollbackTo)

三、實(shí)戰(zhàn)案例:用戶轉(zhuǎn)賬

我們以一個(gè)“用戶轉(zhuǎn)賬”的例子來演示事務(wù)操作。

1. 定義模型

package main

import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"log"
)

type User struct {
	ID      uint   `gorm:"primaryKey"`
	Name    string `gorm:"size:100"`
	Balance int    // 賬戶余額
}

var db *gorm.DB

func initDB() {
	dsn := "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True&loc=Local"
	var err error
	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal("數(shù)據(jù)庫(kù)連接失敗:", err)
	}
	_ = db.AutoMigrate(&User{})
}

2. 使用事務(wù)完成轉(zhuǎn)賬

// Transfer 轉(zhuǎn)賬函數(shù):fromID -> toID,金額 amount
func Transfer(fromID, toID uint, amount int) error {
	return db.Transaction(func(tx *gorm.DB) error {
		var from, to User

		// 查詢轉(zhuǎn)出賬戶
		if err := tx.First(&from, fromID).Error; err != nil {
			return err
		}
		if from.Balance < amount {
			return fmt.Errorf("余額不足")
		}

		// 扣減余額
		if err := tx.Model(&from).Update("balance", from.Balance-amount).Error; err != nil {
			return err
		}

		// 查詢轉(zhuǎn)入賬戶
		if err := tx.First(&to, toID).Error; err != nil {
			return err
		}

		// 增加余額
		if err := tx.Model(&to).Update("balance", to.Balance+amount).Error; err != nil {
			return err
		}

		// 所有操作成功 -> 提交事務(wù)
		return nil
	})
}

3. 測(cè)試轉(zhuǎn)賬

func main() {
	initDB()

	// 初始化兩位用戶
	db.Create(&User{Name: "Alice", Balance: 100})
	db.Create(&User{Name: "Bob", Balance: 50})

	// 轉(zhuǎn)賬:Alice -> Bob 30元
	err := Transfer(1, 2, 30)
	if err != nil {
		log.Println("轉(zhuǎn)賬失敗:", err)
	} else {
		log.Println("轉(zhuǎn)賬成功")
	}

	var users []User
	db.Find(&users)
	log.Println("當(dāng)前用戶余額:", users)
}

四、運(yùn)行效果

初始狀態(tài):

Alice: 100
Bob:   50

轉(zhuǎn)賬成功后:

Alice: 70
Bob:   80

如果 Alice 余額不足,事務(wù)會(huì)回滾:

轉(zhuǎn)賬失敗: 余額不足
Alice: 100
Bob:   50

五、事務(wù)處理注意事項(xiàng)

事務(wù)函數(shù)返回 error

  • 返回 nil → 提交事務(wù)
  • 返回 error → 回滾事務(wù)

不要在事務(wù)中使用全局 db

必須用傳入的 tx 對(duì)象,確保操作在同一事務(wù)內(nèi)。

事務(wù)適合小而快的操作

長(zhǎng)時(shí)間事務(wù)會(huì)占用鎖,可能導(dǎo)致性能下降。

六、總結(jié)

通過本案例,我們學(xué)習(xí)了:

  • 事務(wù)的基本概念(ACID)
  • GORM 的事務(wù) API(推薦 db.Transaction()
  • 用事務(wù)實(shí)現(xiàn) 用戶轉(zhuǎn)賬 功能

事務(wù)在業(yè)務(wù)中非常常見,掌握它能讓你的數(shù)據(jù)庫(kù)操作更加安全可靠。

到此這篇關(guān)于Go語言結(jié)合GORM實(shí)現(xiàn)數(shù)據(jù)庫(kù)事務(wù)處理的示例代碼的文章就介紹到這了,更多相關(guān)Go語言數(shù)據(jù)庫(kù)事務(wù)處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go利用embed包實(shí)現(xiàn)靜態(tài)資源嵌入的方案

    Go利用embed包實(shí)現(xiàn)靜態(tài)資源嵌入的方案

    在很多?Go?項(xiàng)目中,程序除了核心代碼之外,往往還需要依賴一些靜態(tài)資源,傳統(tǒng)做法通常是把這些文件與程序一起打包部署,但這樣會(huì)帶來一些問題,例如部署復(fù)雜、路徑管理困難、發(fā)布時(shí)需要攜帶額外文件等,因此本文給大家介紹了Go利用embed包實(shí)現(xiàn)靜態(tài)資源嵌入的方案
    2026-03-03
  • Go一站式配置管理工具Viper的使用教程

    Go一站式配置管理工具Viper的使用教程

    Viper是一個(gè)方便Go語言應(yīng)用程序處理配置信息的庫(kù),它可以處理多種格式的配置,這篇文章主要為大家介紹了它的具體使用教程,需要的可以參考下
    2023-08-08
  • golang開發(fā)安裝go-torch火焰圖操作步驟

    golang開發(fā)安裝go-torch火焰圖操作步驟

    這篇文章主要為大家介紹了golang開發(fā)安裝go-torch火焰圖操作步驟
    2021-11-11
  • 淺談Go中SIGTERM信的實(shí)現(xiàn)

    淺談Go中SIGTERM信的實(shí)現(xiàn)

    在Go語言中優(yōu)雅處理SIGTERM信號(hào)需通過os/signal包實(shí)現(xiàn),包括信號(hào)注冊(cè)、異步監(jiān)聽和資源清理,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-09-09
  • Go語言在終端打開實(shí)現(xiàn)進(jìn)度條處理數(shù)據(jù)方法實(shí)例

    Go語言在終端打開實(shí)現(xiàn)進(jìn)度條處理數(shù)據(jù)方法實(shí)例

    這篇文章主要介紹了Go語言在終端打開實(shí)現(xiàn)進(jìn)度條處理數(shù)據(jù)方法實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Go?gRPC服務(wù)雙向流式RPC教程

    Go?gRPC服務(wù)雙向流式RPC教程

    這篇文章主要為大家介紹了Go?gRPC服務(wù)雙向流式RPC教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • go語言開發(fā)環(huán)境安裝及第一個(gè)go程序(推薦)

    go語言開發(fā)環(huán)境安裝及第一個(gè)go程序(推薦)

    這篇文章主要介紹了go語言開發(fā)環(huán)境安裝及第一個(gè)go程序,這篇通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • go micro集成鏈路跟蹤的方法和中間件原理解析

    go micro集成鏈路跟蹤的方法和中間件原理解析

    這篇文章主要介紹了go-micro集成鏈路跟蹤的方法和中間件原理,關(guān)于Http或者說是Restful服務(wù)的鏈路跟蹤,go-micro的httpClient支持CallWrapper,可以用WrapCall來添加鏈路跟蹤的CallWrapper,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-05-05
  • 使用pprof分析golang內(nèi)存泄露問題及解決

    使用pprof分析golang內(nèi)存泄露問題及解決

    這篇文章主要介紹了使用pprof分析golang內(nèi)存泄露問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • go語言轉(zhuǎn)換json字符串為json數(shù)據(jù)的實(shí)現(xiàn)

    go語言轉(zhuǎn)換json字符串為json數(shù)據(jù)的實(shí)現(xiàn)

    本文主要介紹了go語言轉(zhuǎn)換json字符串為json數(shù)據(jù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03

最新評(píng)論

兴仁县| 开封市| 台南市| 河津市| 双流县| 高碑店市| 盐亭县| 宣化县| 郓城县| 砚山县| 南汇区| 洛阳市| 合山市| 青神县| 武邑县| 阜城县| 定州市| 扎兰屯市| 烟台市| 司法| 临漳县| 普兰店市| 瑞昌市| 原阳县| 丹江口市| 辉县市| 绥江县| 班戈县| 石嘴山市| 潼关县| 肃南| 易门县| 孟村| 紫阳县| 马尔康县| 南城县| 榆树市| 古蔺县| 霍林郭勒市| 宁国市| 元阳县|