|
|
|
|
|
by jrockway
1985 days ago
|
|
I think it's necessary to leak the details of the mutex until you have some sort of transaction object to abstract that away. In a concurrent workload, these two things are different: store.Lock()
store.WriteKey("foo", "bar")
x := store.ReadKey("foo")
store.Unlock()
// x is always "bar"
And: store.Lock()
store.WriteKey("foo", "bar")
store.Unlock()
store.Lock()
x := store.ReadKey("foo")
store.Unlock()
// x could be whatever another goroutine set "foo" to, not the "bar" that you just wrote.
In a more complicated app, you'll have library that acts as the datastore, with transaction objects that abstract away the actual mutex (which will be something more complicated): var x string
err := db.DoTx(func(tx *Tx) {
tx.Write("foo", "bar")
x = tx.Read("foo")
})
if err != nil { ... }
// what x is depends on the details of your database; maybe you're running at "read uncommitted", maybe you're running at "serializable".
But, even in the simple examples, it's worth thinking about the difference between lock { write; read } and lock { write }; lock { read }. |
|