不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • Langchain
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • GO基础

  • 面向对象

  • 并发编程

  • 常用库

  • 数据库操作

    • GORM

    • sqlx

    • database-sql

    • GORMv2

      • 01.GORM入门
      • 02.CRUD接口
      • 03.关联
      • 04.其他
        • 01.事务
          • 1.1 禁用默认事务
          • 1.2 事务
          • 1.3 嵌套事务
          • 1.4 手动事务
          • 1、方法说明
          • 2、示例
          • 1.5 SavePoint、RollbackTo
        • 02.连接mysql
          • 2.1 基本连接
          • 2.2 连接池
    • go-redis

    • redigo

    • elastic

  • Beego框架

  • Beego商城

  • GIN框架

  • GIN论坛

  • 微服务

  • 设计模式

  • Go
  • 数据库操作
  • GORMv2
xiaonaiqiang
2022-04-01
目录

04.其他

# 01.事务

# 1.1 禁用默认事务

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

// 全局禁用
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
  SkipDefaultTransaction: true,
})

// 持续会话模式
tx := db.Session(&Session{SkipDefaultTransaction: true})
tx.First(&user, 1)
tx.Find(&users)
tx.Model(&user).Update("Age", 18)
1
2
3
4
5
6
7
8
9
10

# 1.2 事务

package main

import (
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// User 表的结构体ORM映射
type User struct {
	ID       int64     `json:"id" gorm:"primary_key"`
	Name     string    `json:"name" gorm:"not null" bind:"required"`
	Age      int       `json:"age"`
	Birthday time.Time `json:"birthday" gorm:"column:birthday"`
}

func main() {
	// 0、连接数据库
	dsn := "root:1@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	// 1、实现事务操作
	db.Transaction(func(tx *gorm.DB) error {
		// 当前这个语句是一个正常语句,但是下面的语句由于ID=1的用户已经存在,所以会抛出异常
		// 查看数据库可以发现这两天数据都没有创建,实现了事务操作
		if err := tx.Create(&User{Name: "root2", Age: 10, Birthday: time.Now()}).Error; err != nil {

			return err  // 返回任何错误都会回滚事务
		}
		if err := tx.Create(&User{ID: 1, Birthday: time.Now()}).Error; err != nil {
			return err
		}
		return nil  // 返回 nil 提交事务
	})
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 1.3 嵌套事务

  • GORM 支持嵌套事务,您可以回滚较大事务内执行的一部分操作
db.Transaction(func(tx *gorm.DB) error {
  tx.Create(&user1)

  tx.Transaction(func(tx2 *gorm.DB) error {
    tx2.Create(&user2)
    return errors.New("rollback user2") // Rollback user2
  })

  tx.Transaction(func(tx2 *gorm.DB) error {
    tx2.Create(&user3)
    return nil
  })

  return nil
})

// Commit user1, user3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 1.4 手动事务

# 1、方法说明

  • Gorm 支持直接调用事务控制方法(commit、rollback)
// 开始事务
tx := db.Begin()

// 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
tx.Create(...)

// ...

// 遇到错误时回滚事务
tx.Rollback()

// 否则,提交事务
tx.Commit()
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2、示例

func CreateAnimals(db *gorm.DB) error {
  // 再唠叨一下,事务一旦开始,你就应该使用 tx 处理数据
  tx := db.Begin()
  defer func() {
    if r := recover(); r != nil {
      tx.Rollback()
    }
  }()

  if err := tx.Error; err != nil {
    return err
  }

  if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
     tx.Rollback()
     return err
  }

  if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
     tx.Rollback()
     return err
  }

  return tx.Commit().Error
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 1.5 SavePoint、RollbackTo

  • GORM 提供了 SavePoint、Rollbackto 方法,来提供保存点以及回滚至保存点功能
tx := db.Begin()
tx.Create(&user1)

tx.SavePoint("sp1")
tx.Create(&user2)
tx.RollbackTo("sp1") // Rollback user2

tx.Commit() // Commit user1
1
2
3
4
5
6
7
8

# 02.连接mysql

# 2.1 基本连接

package main

import (
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func main() {
	dsn := "root:1@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(db)  // &{0xc00018a630 <nil> 0 0xc000198380 1}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  • MySQl 驱动程序提供了 一些高级配置 (opens new window) 可以在初始化过程中使用
db, err := gorm.Open(mysql.New(mysql.Config{
  DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // DSN data source name
  DefaultStringSize: 256, // string 类型字段的默认长度
  DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
  DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
  DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
  SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{})
1
2
3
4
5
6
7
8

# 2.2 连接池

  • GORM 使用 database/sql (opens new window) 维护连接池
package mysql

import (
	"database/sql"
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DBConn *gorm.DB

func Init() {
	//dsn := "root:1@tcp(127.0.0.1:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"
	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		"root", "1", "127.0.0.1:3306", "test_db")
	// GORM 使用 database/sql 维护连接池
	sqlDB, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(fmt.Sprintf("sql.Open err, \v", err))
	}
	// SetMaxIdleConns 设置空闲连接池中连接的最大数量
	sqlDB.SetMaxIdleConns(10)
	// SetMaxOpenConns 设置打开数据库连接的最大数量。
	sqlDB.SetMaxOpenConns(100)
	gormDB, err := gorm.Open(mysql.New(mysql.Config{
		Conn: sqlDB,
	}), &gorm.Config{
		//禁用外键生成
		DisableForeignKeyConstraintWhenMigrating: true,
		//Logger:     newLogger, //重新修改数据库日志配置
	})
	if err != nil {
		panic(fmt.Sprintf("链接数据库失败\v", err))
	}
	DBConn = gormDB
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
上次更新: 2024/3/13 15:35:10
03.关联
01.go-redis包

← 03.关联 01.go-redis包→

最近更新
01
05.快递Agent智能体
06-04
02
200.AI Agent核心概念
06-04
03
105.Agent智能体梳理
06-04
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式