[erlang-questions] Couple of questions about mnesia locking
Sat Apr 4 22:14:12 CEST 2009
I know a write lock would eventually be acquired, but aren't locks acquired
AS the functions in the transaction are called? Like wouldn't it do this:
NodeA reads balance of 5; gets read lock on record
NodeB reads balance of 5; gets read lock on record
NodeA writes balance of 10; gets write lock on record
NodeB writes balance of 15; gets write lock on record
^ Obviously this would be bad
Or does mnesia read the entire transaction first and then apply all of the
locks before doing any of the actions? I don't think this is the case
because then functions such as mnesia:wread would be necessary.
On Sat, Apr 4, 2009 at 3:59 PM, Hynek Vychodil <>wrote:
> Write operation will require aquiring write lock, obviously.
> On Sat, Apr 4, 2009 at 7:54 PM, ryeguy <> wrote:
>> Hmm..well what if we had a transaction where we add to a bank account
>> balance. You obviously read the balance then increment it.
>> If NodeA and NodeB both have replicas of the table containing the
>> balance, couldn't this happen:
>> NodeA reads balance of 5
>> NodeB reads balance of 5
>> NodeA writes balance of 10
>> NodeB writes balance of 15
>> Since there is no read lock on each node? I'm assuming it would work
>> like this because, if I understand correctly, the locks are acquired
>> AS the transaction processes, and not the second the transaction fun
>> is executed, right?
>> In this situation, is the solution to simply just grab a write lock on
>> the record when reading it?
>> This poses another question: how do you acquire a write lock on a
>> record when you do an index read?
>> On Apr 4, 7:31 am, Richard Andrews <> wrote:
>> > > If I wanted to check if a username is in use before registering an
>> > > account like this:
>> > > F=fun()->
>> > > case is_username_available(User) of %% does a mnesia:read to see if
>> > > there is a record with that username
>> > > false -> throw(username_in_use);
>> > > true -> mnesia:write(User)
>> > > end,
>> > > mnesia:transaction(F).
>> > > Don't I have a potential race condition here? Since there is no record
>> > > to lock because it doesn't exist, how can mnesia guarantee another
>> > > process isn't also going to write that same Username to the database?
>> > > If I'm doing this wrong, what's the right way? A table lock (eww)?
>> > You could use a gatekeeper - a singleton process on only one node which
>> is allowed to create usernames. Creators make a request to the gatekeeper
>> which serialises the requests and therefore prevents the race. The problem
>> then shifts to process registration consistency and takeover in the case of
>> the gatekeeper failure.
>> > Sharding/splitting the gatekeeper responsibility by eg. username first
>> letter would quarantine the damage from a gatekeeper failure.
>> > > My second question is regarding a quote from the mnesia manual:
>> > > "Write locks are normally acquired on all nodes where a replica of the
>> > > table resides (and is active). Read locks are acquired on one node
>> > > (the local one if a local replica exists). "
>> > > What does it mean read locks are acquired on one node? What would
>> > > happen when a table is distributed? Wouldn't that defeat the purpose?
>> > A read lock on any node prevents a write lock from being acquired on
>> that item.
>> > A write lock must be acquired on *all* nodes so it is sufficient to take
>> a read lock on any one node to block a write lock from being acquired.
>> > --
>> > Rich
>> > Enjoy a safer web experience. Upgrade to the new Internet Explorer
>> 8 optimised for Yahoo!7. Get it now.
>> > _______________________________________________
>> > erlang-questions mailing list
>> > ://
>> erlang-questions mailing list
> --Hynek (Pichi) Vychodil
> Analyze your data in minutes. Share your insights instantly. Thrill your
> boss. Be a data hero!
> Try Good Data now for free: www.gooddata.com
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the erlang-questions