时间:2022-09-12来源:www.pcxitongcheng.com作者:电脑系统城
为了确保数据一致性,在项目中会经常用到事务处理,回滚操作还是比较常见的需求;事务处理可以用来维护数据库的完整性,保证成批的sql语句要么全部都执行,要么全不执行,对于MySQL事务相信大家应该都不陌生,这篇文章主要总结一下在Go语言中Gorm是如何实现事务的;感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
gorm事务默认是开启的。为了确保数据一致性,Gorm会在事务里执行写入操作(增删改)。
如果对数据一致性要求不高的话,可以在初始化时禁用它,性能将提升大约30%。
一般不推荐禁用。
1 2 3 4 |
// 全局禁用 db, err := gorm.Open(sqlite.Open( "gorm.db" ), &gorm.Config{ SkipDefaultTransaction: true , }) |
通过db.Transaction函数实现事务,如果闭包函数返回错误,则回滚事务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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事务用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// 开启事务 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 支持嵌套事务,可以回滚较大事务内执行的一部分操作,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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 |
GORM 提供了 SavePoint、Rollbackto 来提供保存点以及回滚至保存点,例如:
1 2 3 4 5 6 7 8 |
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事务主要用到了三个函数:
到此这篇关于详解如何利用GORM实现MySQL事务的文章就介绍到这了
2024-07-16
如何使用 Go 依赖库管理器修复损坏的依赖项?2024-07-07
Java框架如何简化代码的调试过程2023-03-17
Python 使用tf-idf算法计算文档关键字权重并生成词云的方法有这么一段代码,可以先看一下有没有什么问题,作用是输入一段json字符串,反序列化成map,然后将另一个inputMap的内容,merge进这个map 1 2 3 4 5 6 7 8 9 10 11 12 13 14...
2023-03-15
由于数据库的类型为Data 类型,所以插入数据库的时候我先把前端传入的string类型的时间转为Time 再插入。 Go 提供了两种插入的方式,即time.Parse 和 time.ParseInLocation 。两种方式,他们的差异比较大。...
2023-03-09