golang gorm —— 事务、回滚、savepoint

2023-10-11 06:28

本文主要是介绍golang gorm —— 事务、回滚、savepoint,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

gorm事务

model定义

type Roles []stringtype Teacher struct {gorm.ModelName     string   `gorm:"size:256"`Email    string   `gorm:"size:256"`Salary   float64  `gorm:"scale:2;precision:7"`   // 指定小数部分宽度为2,列宽度为7. 列宽:【整数部分+小数部分的总长度】【不含小数点】Age      uint8    `gorm:"check:age>30"`Birthday int64    `gorm:"serializer:unixtime;type:time"`  // 反序列化方式 unixtime, 类型为timeRoles    Roles    `gorm:"serializer:json"`JobInfo  Job      `gorm:"embedded;embeddedPrefix:job_"`   // 嵌套字段, 嵌入字段的列名前缀job_JobInfo2 Job      `gorm:"type:bytes;serializer:gob"`      // 字节流类型,gob反序列化,go自己的序列化方法,跨语言项目的时候,不建议用
}type Job struct {Title    stringLocation string
}type Course struct {gorm.ModelName   string  `gorm:"size:256"`Price  float64 `gorm:"scale:2;precision:7"`UserID uint    `gorm:"type:int"`
}
自动事务

gorm提供了自动事务的机制,不需要我们手动提交和回滚

func Transaction() {t := Teacher{Name:   "yuan",Age:    41,Salary: 122345.123,Email:  "yuan@test.com",}c := Course{Name:  "golang",Price: 12345.1234,}DB.Transaction(func(tx *gorm.DB) error {if err := tx.Create(&t).Error; err != nil {// 返回err 会自动回滚事务return err}c.UserID = t.IDif err := tx.Create(&c).Error; err != nil {return err}// 返回nil 则提交事务return nil})
}
嵌套事务

gorm事务可以嵌套,大事务里嵌套小事务,只有大事务成功提交,必须大事务提交成功,内部嵌套的事务才能提交成功。如果失败了,可以回滚嵌套的事务。

注意:嵌套事务不应在gorm中大量使用,因为其不支持预编译

func NestTransaction() {t := Teacher{Name:   "yuan",Age:    41,Salary: 122345.123,Email:  "yuan@test.com",}t1 := Teacher{Name:   "yuan2",Age:    40,Salary: 12345.123,Email:  "yuan@test.com",,}t2 := Teacher{Name:   "yuan3",Age:    50,Salary: 12345.123,Email:  "yuan@test.com",,}DB.Transaction(func(tx *gorm.DB) error {if err := tx.Create(&t).Error; err != nil {return err}tx.Transaction(func(tx1 *gorm.DB) error {if err := tx1.Create(&t1).Error; err != nil {return err}return nil})tx.Transaction(func(tx1 *gorm.DB) error {if err := tx1.Create(&t2).Error; err != nil {return err}return nil})return nil})
}
手动事务

gorm也提供了begin, rollback等接口支持手动事务的操作

func ManualTransaction() {t := Teacher{Name:   "yuan",Age:    41,Salary: 122345.123,Email:  "yuan@test.com",}c := Course{Name:  "golang",Price: 12345.1234,}tx := DB.Begin()defer func() {if err := recover(); err != nil {tx.Rollback()}}()if tx.Error != nil {log.Fatal(tx.Error)return}if err := tx.Create(&t).Error; err != nil {tx.Rollback()return}c.UserID = t.IDif err := tx.Create(&c).Error; err != nil {tx.Rollback()return}tx.Commit()
}
检查点savePoint

gorm也提供了savePoint的机制来支持事务的分段提交,回滚到某个特定的savePoint(RollbackTo)

func SavePointTransaction() {t := Teacher{Name:   "yuan",Age:    41,Salary: 122345.123,Email:  "yuan@test.com",}c := Course{Name:  "golang",Price: 12345.1234,}tx := DB.Begin()defer func() {if err := recover(); err != nil {tx.Rollback()}}()if tx.Error != nil {log.Fatal(tx.Error)return}if err := tx.Create(&t).Error; err != nil {tx.Rollback()return}// 创建savepointtx.SavePoint("teacher")c.UserID = t.IDif err := tx.Create(&c).Error; err != nil {// 回滚到对应savepointtx.RollbackTo("teacher")return}tx.Commit()
}

这篇关于golang gorm —— 事务、回滚、savepoint的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/186172

相关文章

MySql 事务练习

事务(transaction) -- 事务 transaction-- 事务是一组操作的集合,是一个不可分割的工作单位,事务会将所有的操作作为一个整体一起向系统提交或撤销请求-- 事务的操作要么同时成功,要么同时失败-- MySql的事务默认是自动提交的,当执行一个DML语句,MySql会立即自动隐式提交事务-- 常见案例:银行转账-- 逻辑:A给B转账1000:1.查询

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

Golang进程权限调度包runtime

关于 runtime 包几个方法: Gosched:让当前线程让出 cpu 以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行GOMAXPROCS:设置最大的可同时使用的 CPU 核数Goexit:退出当前 goroutine(但是defer语句会照常执行)NumGoroutine:返回正在执行和排队的任务总数GOOS:目标操作系统NumCPU:返回当前系统的 CPU 核数量 p

Golang 网络爬虫框架gocolly/colly(五)

gcocolly+goquery可以非常好地抓取HTML页面中的数据,但碰到页面是由Javascript动态生成时,用goquery就显得捉襟见肘了。解决方法有很多种: 一,最笨拙但有效的方法是字符串处理,go语言string底层对应字节数组,复制任何长度的字符串的开销都很低廉,搜索性能比较高; 二,利用正则表达式,要提取的数据往往有明显的特征,所以正则表达式写起来比较简单,不必非常严谨; 三,使

Golang网络爬虫框架gocolly/colly(四)

爬虫靠演技,表演得越像浏览器,抓取数据越容易,这是我多年爬虫经验的感悟。回顾下个人的爬虫经历,共分三个阶段:第一阶段,09年左右开始接触爬虫,那时由于项目需要,要访问各大国际社交网站,Facebook,myspace,filcker,youtube等等,国际上叫得上名字的社交网站都爬过,大部分网站提供restful api,有些功能没有api,就只能用http抓包工具分析协议,自己爬;国内的优酷、

Golang网络爬虫框架gocolly/colly(三)

熟悉了《Golang 网络爬虫框架gocolly/colly 一》和《Golang 网络爬虫框架gocolly/colly 二》之后就可以在网络上爬取大部分数据了。本文接下来将爬取中证指数有限公司提供的行业市盈率。(http://www.csindex.com.cn/zh-CN/downloads/industry-price-earnings-ratio) 定义数据结构体: type Zhj

Golang支持平滑升级的HTTP服务

前段时间用Golang在做一个HTTP的接口,因编译型语言的特性,修改了代码需要重新编译可执行文件,关闭正在运行的老程序,并启动新程序。对于访问量较大的面向用户的产品,关闭、重启的过程中势必会出现无法访问的情况,从而影响用户体验。 使用Golang的系统包开发HTTP服务,是无法支持平滑升级(优雅重启)的,本文将探讨如何解决该问题。 一、平滑升级(优雅重启)的一般思路 一般情况下,要实现平滑

Golang服务平滑重启

与重载配置相同的是我们也需要通过信号来通知server重启,但关键在于平滑重启,如果只是简单的重启,只需要kill掉,然后再拉起即可。平滑重启意味着server升级的时候可以不用停止业务。 我们先来看下Github上有没有相应的库解决这个问题,然后找到了如下三个库: facebookgo/grace - Graceful restart & zero downtime deploy for G

Golang test编译使用

创建文件my_test.go package testsimport "testing"func TestMy(t *testing.T) {t.Log("TestMy")} 通常用法: $ go test -v -run TestMy my_test.go=== RUN TestMyTestMy: my_test.go:6: TestMy--- PASS: TestMy (0.

Golang GUI入门——andlabs ui

官方不提供gui标准库,只好寻求第三方库。 https://github.com/google/gxui 这个gui库是谷歌内部人员提供的,并不是谷歌官方出品,现在停止维护,只好作罢。 第三方gui库 找了好多,也比较了好多,最终决定使用的是还是 https://github.com/andlabs/ui 相信golang gui还会发展的更好,期待更优秀的gui库 由于andlabs