我的结构定义如下:
type transactionList map[string]Transaction
type ActiveTransactions struct {
mtx sync.Mutex
trm transactionList
}
此结构定义了几种方法:
func (act *ActiveTransactions) NewTransaction(id string, myPayload Payload) {
act.mtx.Lock()
act.trm[id] = Transaction{currentState: FirstState, Payload: myPayload}
act.mtx.Unlock()
}
func (act *ActiveTransactions) GetState(id string) TState {
act.mtx.Lock()
state := act.trm[id].currentState
act.mtx.Unlock()
return state
}
func (act *ActiveTransactions) UpdateState(id string, newState TState) {
act.mtx.Lock()
tmp := act.trm[id]
tmp.currentState = newState
act.trm[id] = tmp
act.mtx.Unlock()
}
此类型创建一次,并由多个goroutines访问。当我运行代码时,由于并发读/写映射访问,它偶尔会引起恐慌(这对我来说并不完全清楚,因为访问映射受sync.Mutex
保护。)
我尝试使用-race选项运行代码并且它也检测到竞争条件(从-race输出我可以看到GetState和NewTransaction方法发生竞争)
这里发生了什么?调用Lock()
后,是否应该通过mtx保护trm?从示例中,我在文档和教程中搜索了模式看起来没问题。显然,有些事情是错的,但它让我望而却步。