gorm樂(lè)觀鎖使用小結(jié)
前言
樂(lè)觀鎖,顧名思義,就是保持樂(lè)觀態(tài)度,在數(shù)據(jù)并發(fā)過(guò)程中,不會(huì)加鎖,而是在數(shù)據(jù)提交之后,才會(huì)檢查沖突,這通過(guò)在數(shù)據(jù)表中增加一個(gè)版本號(hào)(version)字段來(lái)實(shí)現(xiàn)。如果數(shù)據(jù)在事務(wù)處理期間未被其他事務(wù)修改,那么版本號(hào)就不會(huì)發(fā)生變化,事務(wù)可以安全提交。如果版本號(hào)發(fā)生變化,說(shuō)明有沖突發(fā)生,事務(wù)需要回滾或重新嘗試
grom樂(lè)觀鎖機(jī)制
gorm樂(lè)觀鎖依賴(lài)安裝
Gorm是go中一個(gè)優(yōu)秀持久化框架,也提供了樂(lè)觀鎖機(jī)制,通過(guò)以下命令安裝依賴(lài)
go get -u gorm.io/plugin/optimisticlock
gorm樂(lè)觀鎖使用
在定義實(shí)體類(lèi)過(guò)程中,通過(guò)加上一個(gè)Version版本號(hào)控制
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"` // 創(chuàng)建時(shí)間
UpdatedTime time.Time `gorm:"column:update_time;datetime(3);autoUpdateTime" json:"updateTime"` // 更新時(shí)間
}
創(chuàng)建一個(gè)user表
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;
插入數(shù)據(jù)
插入一條id為2的數(shù)據(jù)
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"` // 創(chuàng)建時(shí)間
UpdatedTime time.Time `gorm:"column:update_time;datetime(3);autoUpdateTime" json:"updateTime"` // 更新時(shí)間
}
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, // 使用單數(shù)表名
},
})
if err != nil {
log.Println("連接數(shù)據(jù)庫(kù)錯(cuò)誤:", 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)
}

這時(shí)候版本為1
版本號(hào)更新
這時(shí)候把id=2的數(shù)據(jù)查出來(lái),進(jìn)行更新操作,版本號(hào)會(huì)發(fā)生變化
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"` // 創(chuàng)建時(shí)間
UpdatedTime time.Time `gorm:"column:update_time;datetime(3);autoUpdateTime" json:"updateTime"` // 更新時(shí)間
}
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, // 使用單數(shù)表名
},
})
if err != nil {
log.Println("連接數(shù)據(jù)庫(kù)錯(cuò)誤:", 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)
}

這時(shí)候可以看到更新成功,版本號(hào)變成2
總結(jié)
樂(lè)觀鎖機(jī)制,可以有效保證在并發(fā)過(guò)程修改數(shù)據(jù)過(guò)程中的不安全問(wèn)題,但是后面更新失敗的問(wèn)題,根據(jù)項(xiàng)目,具體問(wèn)題具體分析
到此這篇關(guān)于gorm樂(lè)觀鎖使用小結(jié)的文章就介紹到這了,更多相關(guān)gorm 樂(lè)觀鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go|使用Options模式和建造者模式創(chuàng)建對(duì)象實(shí)戰(zhàn)
這篇文章主要介紹了Go使用Options模式和建造者模式創(chuàng)建對(duì)象實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
golang 歸并排序,快速排序,堆排序的實(shí)現(xiàn)
本文主要介紹了golang 歸并排序,快速排序,堆排序的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Golang語(yǔ)言JSON解碼函數(shù)Unmarshal的使用
本文主要介紹了Golang語(yǔ)言JSON解碼函數(shù)Unmarshal的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
淺析Go使用定時(shí)器時(shí)如何避免潛在的內(nèi)存泄漏陷阱
這篇文章來(lái)和大家一起探討一下Go?中如何高效使用?timer,特別是與select?一起使用時(shí),如何防止?jié)撛诘膬?nèi)存泄漏問(wèn)題,感興趣的可以了解下2024-01-01
Go語(yǔ)言Swagger實(shí)現(xiàn)為項(xiàng)目生成 API 文檔
Swagger 是一個(gè)基于 OpenAPI 規(guī)范設(shè)計(jì)的工具,用于為 RESTful API 生成交互式文檔,下面小編就來(lái)介紹一下如何在 Go 項(xiàng)目中集成 Swagger,特別是結(jié)合 Gin 框架生成 API 文檔2025-03-03
Go語(yǔ)言實(shí)現(xiàn)二進(jìn)制與十進(jìn)制互轉(zhuǎn)的示例代碼
這篇文章主要和大家詳細(xì)介紹了Go語(yǔ)言中實(shí)現(xiàn)二進(jìn)制與十進(jìn)制互相轉(zhuǎn)換的示例代碼,文中的代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-05-05
Go如何優(yōu)雅的關(guān)閉goroutine協(xié)程
本文將介紹首先為什么需要主動(dòng)關(guān)閉goroutine,并介紹如何在Go語(yǔ)言中關(guān)閉goroutine的常見(jiàn)套路,包括傳遞終止信號(hào)和協(xié)程內(nèi)部捕捉終止信號(hào),之后,文章列舉了需要主動(dòng)關(guān)閉協(xié)程運(yùn)行的常見(jiàn)場(chǎng)景,希望通過(guò)本文的介紹,讀者能夠掌握如何在適當(dāng)?shù)臅r(shí)候關(guān)閉goroutine2023-05-05

