gorm乐观锁使用小结

Written by

in

文章目录
  • 乐观锁,顾名思义,就是保持乐观态度,在数据并发过程中,不会加锁,而是在数据提交之后,才会检查冲突,这通过在数据表中增加一个版本号(version)字段来实现。如果数据在事务处理期间未被其他事务修改,那么版本号就不会发生变化,事务可以安全提交。如果版本号发生变化,说明有冲突发生,事务需要回滚或重新尝试
  • 乐观锁机制,可以有效保证在并发过程修改数据过程中的不安全问题,但是后面更新失败的问题,根据项目,具体问题具体分析 到此这篇关于gorm乐观锁使用小结的文章就介绍到这了,更多相关gorm 乐观锁内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: Go语言中乐观锁与悲观锁的具体使用
  • 目录
    • 前言
    • grom乐观锁机制
      • gorm乐观锁依赖安装
      • gorm乐观锁使用
      • 创建一个user表
      • 插入数据
      • 版本号更新
    • 总结

      乐观锁,顾名思义,就是保持乐观态度,在数据并发过程中,不会加锁,而是在数据提交之后,才会检查冲突,这通过在数据表中增加一个版本号(version)字段来实现。如果数据在事务处理期间未被其他事务修改,那么版本号就不会发生变化,事务可以安全提交。如果版本号发生变化,说明有冲突发生,事务需要回滚或重新尝试

      Gorm是go中一个优秀持久化框架,也提供了乐观锁机制,通过以下命令安装依赖

      go get -u gorm.io/plugin/optimisticlock
      

      在定义实体类过程中,通过加上一个Version版本号控制

      import "gorm.io/plugin/optimisticlock"
      
      type User struct {
          Id          int64  `gorm:"primary_key;type:bigint(20);not null;column:id;comment:'主键id';" json:"id"`
          UserName    string `gorm:"column:userName"`
          Sex         int    `gorm:"column:sex"`
          Version     optimisticlock.Version
          CreateTime  time.Time `gorm:"column:create_time;datetime(3);autoUpdateTime" json:"createTime"` // 创建时间
          UpdatedTime time.Time `gorm:"column:update_time;datetime(3);autoUpdateTime" json:"updateTime"` // 更新时间
      }
      

      SET NAMES utf8mb4;
      SET FOREIGN_KEY_CHECKS = 0;
      
      -- ----------------------------
      -- Table structure for user
      -- ----------------------------
      DROP TABLE IF EXISTS `user`;
      CREATE TABLE `user`  (
        `id` bigint NOT NULL AUTO_INCREMENT COMMENT ''主键id'',
        `userName` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL,
        `sex` bigint NULL DEFAULT NULL,
        `version` bigint NULL DEFAULT NULL,
        `create_time` datetime(3) NULL DEFAULT NULL,
        `update_time` datetime(3) NULL DEFAULT NULL,
        PRIMARY KEY (`id`) USING BTREE
      ) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;
      
      SET FOREIGN_KEY_CHECKS = 1;
      
      

      插入一条id为2的数据

      package main
      
      import (
          "gorm.io/driver/mysql"
          "gorm.io/gorm"
          "gorm.io/gorm/schema"
          "log"
          "time"
      )
      
      import "gorm.io/plugin/optimisticlock"
      
      type User struct {
          Id          int64  `gorm:"primary_key;type:bigint(20);not null;column:id;comment:'主键id';" json:"id"`
          UserName    string `gorm:"column:userName"`
          Sex         int    `gorm:"column:sex"`
          Version     optimisticlock.Version
          CreateTime  time.Time `gorm:"column:create_time;datetime(3);autoUpdateTime" json:"createTime"` // 创建时间
          UpdatedTime time.Time `gorm:"column:update_time;datetime(3);autoUpdateTime" json:"updateTime"` // 更新时间
      }
      
      func main() {
          dsn := "root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
          db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
             NamingStrategy: schema.NamingStrategy{
                SingularTable: true, // 使用单数表名
             },
          })
          if err != nil {
             log.Println("连接数据库错误:", err)
             return
          }
      
          var user = User{
             UserName: "aaa",
             Sex:      1,
          }
          result := db.Table("user").Create(&user)
          log.Println(result)
          log.Println(user)
          //var user1 User
          //db.Table("user").First(&user1, "id = ?", 1)
          //log.Println(user1)
          //user1.UserName = "bbbb"
          //result1 := db.Table("user").Save(&user1)
          //fmt.Println(result1)
      }
      

      这时候版本为1

      这时候把id=2的数据查出来,进行更新操作,版本号会发生变化

      package main
      
      import (
          "fmt"
          "gorm.io/driver/mysql"
          "gorm.io/gorm"
          "gorm.io/gorm/schema"
          "log"
          "time"
      )
      
      import "gorm.io/plugin/optimisticlock"
      
      type User struct {
          Id          int64  `gorm:"primary_key;type:bigint(20);not null;column:id;comment:'主键id';" json:"id"`
          UserName    string `gorm:"column:userName"`
          Sex         int    `gorm:"column:sex"`
          Version     optimisticlock.Version
          CreateTime  time.Time `gorm:"column:create_time;datetime(3);autoUpdateTime" json:"createTime"` // 创建时间
          UpdatedTime time.Time `gorm:"column:update_time;datetime(3);autoUpdateTime" json:"updateTime"` // 更新时间
      }
      
      func main() {
          dsn := "root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
          db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
             NamingStrategy: schema.NamingStrategy{
                SingularTable: true, // 使用单数表名
             },
          })
          if err != nil {
             log.Println("连接数据库错误:", err)
             return
          }
      
          var user1 User
          db.Table("user").First(&user1, "id = ?", 2)
          log.Println(user1)
          user1.UserName = "bbbb"
          result1 := db.Table("user").Save(&user1)
          fmt.Println(result1)
      }
      

      这时候可以看到更新成功,版本号变成2

      乐观锁机制,可以有效保证在并发过程修改数据过程中的不安全问题,但是后面更新失败的问题,根据项目,具体问题具体分析

      到此这篇关于gorm乐观锁使用小结的文章就介绍到这了,更多相关gorm 乐观锁内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

      您可能感兴趣的文章:

      • Go语言中乐观锁与悲观锁的具体使用

      站内搜索