GORM之事务操作 | 青训营笔记

620 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天


GORM之事务操作

事务

事务在工程中是不可缺少的一个重要部分,几乎所有的操作都会或多或少地涉及到事务,先回忆一下什么是事务。

事务是一组 SQL 语句的集合,要么全部执行,要么全部不执行。

事务的四大特性(ACID):

  • 原子性:一个事务,要么全部执行,要么全部不执行,在事务的执行过程中,发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过 一样。主要是靠 undolog 进行保证的。

  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力。事务隔离级别分为不同的级别:读未提交(Read uncommited),读已提交(Read commited),可重复读(Repeatable read)和串行化(Serializable),主要是靠 MVCC 进行保证的

  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。主要是靠 redo log 进行实现的

  • 一致性:以上三个特性可以保证 一致性:在事务开始之前和事务结束之后,数据库的完整性没有破坏。

GORM中的事务

为了确保数据一致性,GORM 会在事务里执行写入操作(创建、更新、删除)。

定义事务

db.Transaction(func(tx *gorm.DB) error {
  // 在事务中执行一些 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
})

嵌套事务

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

如果你发现了文章出现了错误或有不足,欢迎在评论区和我交流,我看到了一定会回复。

写文章不易,如果你觉得文章对你有帮助,麻烦点一下点赞、收藏,你的支持是我写文章的最大动力!