G

[Golang] GORM框架 锁

RoLingG 2024-10-10

GORM 支持多种类型的锁,例如:

// 基本的 FOR UPDATE 锁
db.Clauses(clause.Locking{Strength: "UPDATE"}).Find(&users)
// SQL: SELECT * FROM `users` FOR UPDATE

上述语句将会在事务(transaction)中锁定选中行(selected rows)。 可以被用于以下场景:当你准备在事务(transaction)中更新(update)一些行(rows)时,并且想要在本事务完成前,阻止(prevent)其他的事务(other transactions)修改你准备更新的选中行。

Strength 也可以被设置为 SHARE ,这种锁只允许其他事务读取(read)被锁定的内容,而无法修改(update)或者删除(delete)。

db.Clauses(clause.Locking{
  Strength: "SHARE",
  Table: clause.Table{Name: clause.CurrentTable},
}).Find(&users)
// SQL: SELECT * FROM `users` FOR SHARE OF `users`

Table选项用于指定将要被锁定的表。 这在你想要 join 多个表,并且锁定其一时非常有用。

你也可以提供如 NOWAIT 的Options,这将尝试获取一个锁,如果锁不可用,导致了获取失败,函数将会立即返回一个error。 当一个事务等待其他事务释放它们的锁时,此Options(Nowait)可以阻止这种行为

上面是官话,其实讲人话一点就是,NOWAIT选项它告诉数据库在尝试获取表锁时不要等待。如果该行、表或者数据库已经被其他事务锁定,则会立即返回一个错误,而不是让当前事务进入等待状态,等待锁被释放。
db.Clauses(clause.Locking{
  Strength: "UPDATE",
  Options: "NOWAIT",
}).Find(&users)
// SQL: SELECT * FROM `users` FOR UPDATE NOWAIT

Options也可以是SKIP LOCKED,设置后将跳过所有已经被其他事务锁定的行(any rows that are already locked by other transactions.)。 这次高并发情况下非常有用:那时你可能会想要对未经其他事务锁定的行进行操作(process )。

PREV
[Golang] GORM框架 视图
NEXT
[Golang] GORM框架 逐步分析→FirstOrCreate

评论(0)

发布评论