前言

在Golang中,并发编程变得容易实现,仅需要起一个goroutine即可开启并发模式:

但是,在并发编程中存在不少需要注意的地方。这篇文章简单讨论下,在多个goroutine对MongoDB数据库进行操作时,保证操作一致性的方法。


问题描述

假设我们起了多个goroutine,如下:


以上代码从数据库中取得所有 `status == true` 的记录,随后对这些记录进行操作,最终将记录的状态设置为 `false`。

仔细一看,这段代码明显存在问题,描述如下:

  • 假设有两个goroutine: goroutineA, goroutineB 都进行了以上操作
  • goroutineA 执行了step1 取出状态为 `true` 的记录,并且进行了 step2 操作
  • 当 goroutineA 执行到 step2 但是 step3 还未执行完成时,goroutineB 也有可能成功执行 step1。随后goroutineB 也执行了 step2。显然,这不是我们所预期的结果。


解决方案

解决问题的主要思路是:

  • 为 status 多设置一个中间状态 pending,代表该记录正在被处理中
  • 添加SetStatus方法,在Update的时候确保 `status`字段未被其他事务改动

参考代码如下:


通过以上方法可以确保不会同时有多个goroutine 对一条数据进行了更新操作。


我的微信公众号: EasyHacking

Go设计模式陆续更新中 github: csxuejin/go-design-patterns