使用互斥锁保护Golang结构,仍然可以通过锁定检测到种族

I have a struct defined as follows:

type transactionList map[string]Transaction
type ActiveTransactions struct {
    mtx sync.Mutex
    trm transactionList
}

This struct has several methods defined:

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()
}

This type is created once and is accessed by multiple goroutines. When I run the code it occasionally panics because of concurrent read/write map access (which is not entirely clear to me since access to the map is protected with sync.Mutex).

I have tried to run the code with -race option and it detects race condition as well (from the -race output I can see that race happens for GetState and NewTransaction methods)

What's happening here? Should trm be protected by mtx once Lock() is called? From the examples, I searched in the docs and tutorials the pattern looks ok. Obviously, something is wrong, but it eludes me.