我的Golang代码使用goroutines从数据库中获取不同的记录,并在记录中的确定字段中增加该值。
我可以避免竞争条件如果我使用Mutex或Channels,但我有一个瓶颈,因为每次访问数据库都会等到上一次访问完成。
我认为我应该为每个不同的记录执行类似于一个Mutex的操作,而不是只为所有记录执行Mutex。
我怎么能这样做?
感谢您的回复。
答案 0 :(得分:1)
在评论中,您说您正在使用Couchbase。如果您要更新的记录仅包含整数,则可以使用Bucket.Incr
内置的原子增量功能。
如果值是较大文档的一部分,则可以使用数据库的"Check and Set"功能。实质上,您希望创建一个执行以下操作的循环:
Bucket.Gets
Bucket.Cas
存储修改后的文档,并传递在(1)中检索到的CAS值。请注意,每次循环检索文档都很重要。如果由于CAS值不正确而导致更新失败,则表示文档在读取和写入之间进行了更新。
答案 1 :(得分:0)
如果数据库有办法处理(即内置的原子计数器),你应该使用它。 如果没有,或者如果你想在go中执行此操作,则可以使用缓冲通道。除非缓冲区已满,否则插入缓冲通道不会阻塞。
然后,要一次一个地处理增量,在goroutine中你可以有类似的东西
for{
select{
value, _ := <-CounterChan
incrementCounterBy(value)
}
}