如何在golang中使用互斥锁(mutex)来锁定特定的值或标识符

huangapple go评论141阅读模式
英文:

How to use mutex to lock on a specific value or identifier in golang

问题

我想在更新余额时避免任何竞态条件。以下是示例代码:

type BalanceHandler struct {
  repo      Repository
  provider  Provider
  mutex     sync.Mutex
}

func (h *BalanceHandler) AddToBalance(userID int64, amount int64) {
  h.mutex.Lock()
  defer h.mutex.Unlock()

  user := h.repo.GetUser(userID)

  bal := h.provider.GetBalance(user.Email())
  newBalance := bal + amount
  h.provider.UpdateBalance(user.Email(), newBalance)
}

我想知道是否有一种方法可以为userID创建互斥锁,以便不同的用户可以并发访问,但对于相同的userID,访问应该是同步的。

英文:

I want to avoid any race condition while updating the balance. Below is the example code

type BalanceHandler struct {
  repo      Repository
  provider  Provider
}

func(h *BalanceHandler) AddToBalance(userID int64, amount int64){
  user := h.repo.GetUser(userID)

  bal := h.provider.GetBalance(user.Email())
  newBalance := bal + amount
  h.provider.UpdateBalance(user.Email(), newBalance)
}

I want to know if there is a way to create mutex specifically for the userID so that different users are allowed concurrent access but for the same userID the access should be synchronised

答案1

得分: 2

解决方案取决于代码中不明显的几个因素。

如果repo.GetUser对于相同的userID返回相同的user实例,并且该用户是指向用户结构体的指针,那么你可以为该用户添加一个互斥锁,在获取后锁定它,在完成后解锁它。

另一个选项是使用共享的map[string]struct{}对象,并记录已锁定的用户ID。你需要一个互斥锁来保护该映射。

英文:

The solution depends on several things not evident from the code.

If repo.GetUser returns the same user instance for the same userID, and if that user is a pointer to a user struct, then you can add a mutex to that user, lock it after you get it, and unlock it when you're done.

Another option is to have a shared map[string]struct{} object, and record locked user IDs. You need a mutex to protect that map.

huangapple
  • 本文由 发表于 2022年9月2日 12:30:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/73577783.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定