[erlang-questions] Couple of questions about mnesia locking

ryeguy <>
Sat Apr 4 19:54:44 CEST 2009


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
> ://www.erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list