[golang gin框架] 9.Gin GORM 中使用事务以及go-ini加载.ini配置文件

一.事务

事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全执行,要么全不执行

1.禁用默认事务

为了确保数据一致性,GORM 会在事务里执行写入操作(创建、更新、删除),如果没有这方面的要求,可以在初始化时禁用它,这将获得大约 30%+ 性能提升,禁用默认的事务代码如下:
package models

//gorm文档: https://gorm.io/zh_CN/docs/index.html
//连接数据库核心代码

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

//全局使用DB,就需要把DB定义成公有的
var DB *gorm.DB
var err error

//自动初始化数据库
func init()  {
    // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
    dsn := "root:123456@tcp(127.0.0.1:3306)/gin?charset=utf8mb4&parseTime=True&loc=Local"
    DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
        SkipDefaultTransaction : true, //禁用事物
        QueryFields: true, // 打印sql
    })
    if err != nil {
        fmt.Println(err)
    }
}
GORM 默认会将单个的 create, update, delete 操作封装在事务内进行处理,以确保数据的完整性。如果想把多个 create, update, delete 操作作为一个原子操作,就要使用Transaction来完成

2.事务相关操作

2.1事务执行流程

要在事务中执行一系列操作,通您可以参照下面的流程来执行
db.Transaction(func(tx *gorm.DB) error {
    // 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
    if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
        // 返回任何错误都会回滚事务
        return err
    }
    if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
        return err
    }
    // 返回 nil 提交事务
    return nil
})

2.2事务(手动控制)

// 开启事务
tx := db.Begin()
// 在事务中做一些数据库操作 (这里应该使用 'tx' ,而不是 'db')
tx.Create(...)
// ... // 有错误时,手动调用事务的 Rollback()
tx.Rollback()
// 无错误时,手动调用事务的 Commit()
tx.Commit()

2.3案例:张三给李四转账

package admin

import (
    "gindemo/models"
    "github.com/gin-gonic/gin"
)

//定义一个BankController结构体,可以实例化结构体访问里面的方法
type BankController struct {
    BaseController  // 继承基础控制器
}

//列表
func (con BankController) Index(c *gin.Context) {
    //开启事务
    tx := models.DB.Begin()
    //抛出异常
    defer func() {
        if r := recover(); r != nil {
            tx.Rollback()
            //遇到错误时回滚事务
            //转账失败
            con.error(c)
            return
        }
    }()
    //panic("异常了")

    // 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
    // 张三给李四转账
    // 张三账号上减去100元
    u1 := models.Bank{Id: 1}
    tx.Find(&u1)
    u1.Balance = u1.Balance - 100
    //判断保存数据是否正确,如果不正确,则回滚
    if err := tx.Save(&u1).Error; err != nil {
        tx.Rollback()
        //转账失败
        con.error(c)
        return
    }
    //李四账号上增加100元
    u2 := models.Bank{Id: 2}
    tx.Find(&u2)
    u2.Balance = u2.Balance + 100
    //判断保存数据是否正确,如果不正确,则回滚
    if err := tx.Save(&u2).Error; err != nil {
        tx.Rollback()
        //转账失败
        con.error(c)
        return
    }
    tx.Commit()
    //转账成功
    con.success(c)
}

更多事务相关,请参考官网:事务 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

二.go-ini加载.ini配置文件

1.go-ini 介绍

go-ini 官方介绍,go-ini 是地表 最强大最方便 最流行 的 Go 语言 INI 文件操作库

Github 地址GitHub - go-ini/ini: Package ini provides INI file read and write functionality in Go

官方文档:go-ini/ini: A fantastic package for INI manipulations in Go

2.go-ini 使用

2.1新建 conf/app.ini

编辑 app.ini 文件并输入以下内容

app_name  = app测试
# 错误级别: DEBUG,INFO,WARNING,ERROR,FATAL
log_level = DEBUG
app_mode  = production

[mysql]
ip       = 127.0.0.1
port     = 3306
user     = root
password = 123456
database = gin

[redis]
ip       = 127.0.0.1
port     = 9376
database = 1

2.2 安装

(1).直接通过命令下载

$ go get gopkg.in/ini.v1
(2).通过go mod tidy命映引入
#1.首先,在main.go文件中 import "gopkg.in/ini.v1",如下:
import (
    "gopkg.in/ini.v1"
)
#然后命令行执行 go mod tidy

2.3 操作刚才创建的ini配置文件

接下来需要编写 main.go 文件来操作刚才创建的配置文件
package main

import (
    "fmt"
    "os"
    "gopkg.in/ini.v1"
)

func main() {
    //演示gopkg.in/ini.v1模块的使用
    cfg, err := ini.Load("./conf/app.ini")
    if err != nil {
        fmt.Printf("Fail to read file: %v", err)
        os.Exit(1)
    }
    // 典型读取操作,默认分区可以使用空字符串表示
    fmt.Println("获取配置根数据:", cfg.Section("").Key("app_name").String())
    fmt.Println("获取配置mysql数据:", cfg.Section("mysql").Key("password").String())
    fmt.Println("获取配置redis数据:", cfg.Section("redis").Key("port").String())

    //给ini写入数据
    //修改某个值然后进行保存
    cfg.Section("").Key("app_name").SetValue("app测试")
    //写入一个新的配置
    cfg.Section("").Key("app_mode").SetValue("production")
    cfg.Section("redis").Key("database").SetValue("1")

    cfg.SaveTo("./conf/app.ini")

    r.Run() // 启动一个web服务
}

[上一节][golang gin框架] 8.Gin GORM原生 SQL以及表关联查询

[下一节][golang gin框架] 10.Gin 商城项目介绍

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值