详解如何利用GORM实现MySQL事务

 更新时间:2022年09月07日 14:12:36   作者:1个俗人  
为了确保数据一致性,在项目中会经常用到事务处理,对于MySQL事务相信大家应该都不陌生。这篇文章主要总结一下在Go语言中Gorm是如何实现事务的;感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助

前言

为了确保数据一致性,在项目中会经常用到事务处理,回滚操作还是比较常见的需求;事务处理可以用来维护数据库的完整性,保证成批的sql语句要么全部都执行,要么全不执行,对于MySQL事务相信大家应该都不陌生,这篇文章主要总结一下在Go语言中Gorm是如何实现事务的;感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

禁用默认事务

gorm事务默认是开启的。为了确保数据一致性,Gorm会在事务里执行写入操作(增删改)。

如果对数据一致性要求不高的话,可以在初始化时禁用它,性能将提升大约30%。

一般不推荐禁用。

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

自动事务

通过db.Transaction函数实现事务,如果闭包函数返回错误,则回滚事务。

db.Transaction(func(tx *gorm.DB) error {
  // 在事务中执行一些 db 操作(从这里开始,您应该使用 'tx' 而不是 'db')
  if err := tx.Create(&User{Name: "Lili"}).Error; err != nil {
    // 返回任何错误都会回滚事务
    return err
  }

  if err := tx.Create(&User{Name: "xiaoming"}).Error; err != nil {
    return err
  }

  // 返回 nil 提交事务
  return nil
})

手动事务

在开发中经常需要数据库事务来保证多个数据库写操作的原子性。例如电商系统中的扣减库存和保存订单。

gorm事务用法:

// 开启事务
tx := db.Begin()

//在事务中执行数据库操作,使用的是tx变量,不是db。

//库存减一
//等价于: UPDATE `goods` SET `stock` = stock - 1  WHERE `goods`.`id` = '2' and stock > 0
//RowsAffected用于返回sql执行后影响的行数
rowsAffected := tx.Model(&goods).Where("stock > 0").Update("stock", gorm.Expr("stock - 1")).RowsAffected
if rowsAffected == 0 {
    //如果更新库存操作,返回影响行数为0,说明没有库存了,结束下单流程
    //这里回滚作用不大,因为前面没成功执行什么数据库更新操作,也没什么数据需要回滚。
    //这里就是举个例子,事务中可以执行多个sql语句,错误了可以回滚事务
    tx.Rollback()
    return
}
err := tx.Create(保存订单).Error

//保存订单失败,则回滚事务
if err != nil {
    tx.Rollback()
} else {
    tx.Commit()
}

嵌套事务

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

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

这里rollback到了sp1的位置,也就是说,数据库中只存了user1这条数据。

小结

关于Go GORM 事务详细介绍的文章就介绍到这了,总的来说Gorm事务的实现非常简单,go语言操作mysql事务主要用到了三个函数:

  • Db.Begin() 开始事务
  • Db.Commit() 提交事务
  • Db.Rollback() 回滚事务

到此这篇关于详解如何利用GORM实现MySQL事务的文章就介绍到这了,更多相关Golang GORM实现MySQL事务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go-zero自定义中间件的几种方式

    go-zero自定义中间件的几种方式

    首先 go-zero 已经为我们提供了很多的中间件的实现,但有时难免有需求需要自定义,这里介绍几种自定义的方法,文中通过代码示例讲解的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2024-07-07
  • Gin与Mysql实现简单Restful风格API实战示例详解

    Gin与Mysql实现简单Restful风格API实战示例详解

    这篇文章主要为大家介绍了Gin与Mysql实现简单Restful风格API示例详解,有需要的朋友可以借鉴参考下希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Go语言遍历map实现(访问map中的每一个键值对)

    Go语言遍历map实现(访问map中的每一个键值对)

    这篇文章主要介绍了Go语言遍历map实现(访问map中的每一个键值对),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 详解Golang如何在编译时注入版本信息

    详解Golang如何在编译时注入版本信息

    这篇文章主要为大家详细介绍了Golang如何在编译时实现注入版本信息,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
    2023-06-06
  • Go语言LeetCode题解706设计哈希映射

    Go语言LeetCode题解706设计哈希映射

    这篇文章主要为大家介绍了Go语言LeetCode题解706设计哈希映射示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Go语言中嵌入式缓存库的用法详解

    Go语言中嵌入式缓存库的用法详解

    Go 语言中有一些非常高效的嵌入式缓存库,groupcache 和 bigcache 是两个非常流行且高性能的库,本文将详细介绍一下二者的用法,有需要的小伙伴可以参考下
    2025-01-01
  • 搭建Go语言的ORM框架Gorm的具体步骤(从Java到go)

    搭建Go语言的ORM框架Gorm的具体步骤(从Java到go)

    很多朋友不知道如何使用Goland软件,搭建一个ORM框架GORM,今天小编给大家分享一篇教程关于搭建Go语言的ORM框架Gorm的具体步骤(从Java到go),感兴趣的朋友跟随小编一起学习下吧
    2022-09-09
  • go-zero使用goctl生成mongodb的操作使用方法

    go-zero使用goctl生成mongodb的操作使用方法

    mongodb是一种高性能、开源、文档型的nosql数据库,被广泛应用于web应用、大数据以及云计算领域,goctl model 为 goctl 提供的数据库模型代码生成指令,目前支持 MySQL、PostgreSQL、Mongo 的代码生成,本文给大家介绍了go-zero使用goctl生成mongodb的操作使用方法
    2024-06-06
  • Golang内存泄露场景与定位方式的实现

    Golang内存泄露场景与定位方式的实现

    Golang有自动垃圾回收机制,但是仍然可能会出现内存泄漏的情况,本文主要介绍了Golang内存泄露场景与定位方式的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-04-04
  • golang中sync.Mutex的实现方法

    golang中sync.Mutex的实现方法

    本文主要介绍了golang中sync.Mutex的实现方法,mutex 主要有两个 method: Lock() 和 Unlock(),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04

最新评论