关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

GORM中使用事务

发布时间:2023-06-26 19:00:38

公司用的还是 v1.x版本,业务场景是先根据条件删除一条记录,同时写入一条新的。 要保证两者要么同时执行成功,要么都不执行。本地demo记录一下:

create table shuang.student (  id int auto_increment  primary key,  name varchar(128) not null,  age int not null,  id_card varchar(128) not null,  last_update date not null )  charset = utf8mb4;

     

 package main  import (  "fmt"  "github.com/davecgh/go-spew/spew"  _ "github.com/go-sql-driver/mysql"  "github.com/jinzhu/gorm"  "os"  "time" )  type Student struct {  ID int64 `gorm:"column:id" db:"id" json:"id" form:"id"`  Name string `gorm:"column:name" db:"name" json:"name" form:"name"`  Age int64 `gorm:"column:age" db:"age" json:"age" form:"age"`  IdCard string `gorm:"column:id_card" db:"id_card" json:"id_card" form:"id_card"`  LastUpdate time.Time `gorm:"column:last_update" db:"last_update" json:"last_update" form:"last_update"` }  func (Student) TableName() string {  return "student" }  func main() {  dsn := "root:12345678@tcp(127.0.0.1:3306)/shuang?charset=utf8mb4&parseTime=True&loc=Local"   db, err := gorm.Open("mysql", dsn)   if err != nil {  fmt.Fprintln(os.Stderr, "connect db addr :", dsn, "err :", err)  panic(fmt.Sprintf("连接数据库失败: %s", err))  }   db.LogMode(true) // 是否打印每条sql   db.DB().SetMaxIdleConns(10)  db.DB().SetMaxOpenConns(200)  db.DB().SetConnMaxLifetime(10 * time.Second)   if err != nil {  panic("failed to connect database")  }   // 用于构造数据  //stu0 := &Student{Name: "爽哥测试333", Age: 200, IdCard: "qwert", LastUpdate: time.Now()}  //// 插入新数据  //errC := db.Create(stu0).Error  //if errC != nil {  // fmt.Printf("插入新纪录错误 err:%#v\n", errC)  //}   var stu Student  db.Table("student").Where("id=?", 36).First(&stu)   spew.Dump("取出的记录为:", stu)   errT := db.Transaction(func(tx *gorm.DB) error {  // 先删  fmt.Println("要删的id是:", stu.ID)   // errD := tx.Where("name=? ", stu.Name).Delete(&stu).Error  // 最好传入一个空的&Student{}  // Limit(1)限制最多只删除一行,需要加在Delete()的前面  errD := tx.Where("name=? ", stu.Name).Limit(1).Delete(&Student{}).Error   if errD != nil {  fmt.Printf("删除纪录错误 err:%#v\n", errD)  return errD  }   // 再故意写入失败(ID冲突),则上面的删除操作需要回滚,原来的记录不能被删掉  stu2 := &Student{Name: stu.Name, Age: stu.Age, IdCard: stu.IdCard, LastUpdate: time.Now(), ID: 37}   errC := tx.Create(stu2).Error   if errC != nil {  fmt.Printf("写入新纪录错误 err:%#v\n", errC)  return errC  }   return nil   })   fmt.Println("事务执行的errT为:", errT)   // 事务生效的标准就是36这条记录不能真的被删掉。执行后和执行前记录完全一样   // 将上面stu2从的ID:37 去掉,再执行代码,则36这条会被删掉,同时生成一行新的记录  }

   

GORM-事务

如何让gorm输出执行的sql


/template/Home/leiyu/PC/Static