[erlang-questions] Couple of questions about mnesia locking

Ulf Wiger <>
Sun Apr 5 23:21:46 CEST 2009


A read lock can be upgraded to a write lock /only/ if there are no other read locks on the object. Otherwise the transaction must wait until the other read locks are released. In your example, this won't happen, and one of the two transactions must restart. You can go for a write lock directly if you want. For index_read(), there isn't a version that lets you specify the lock type, but according to the docs, it takes a read lock on the whole table. Then start by taking a write lock on the table instead.

BR,
Ulf W
-- originalmedd. --
Ämne: Re: [erlang-questions] Couple of questions about mnesia locking
Från: Ryan Lepidi <>
Datum: 2009.04.05 19.51

I apreciate your guys' help. I have a question though, what would happen in
this situation?

NodeA reads balance of 5; gets read lock on record

NodeB reads balance of 5; gets read lock on record   %on another node, so
read lock is possible
NodeB writes balance of 15; gets write lock on record %does the write then
releases the lock

NodeA writes balance of 10; gets write lock on record

NodeA would have a stale value and NodeB would not have to wait for any
locks, so neither of them would restart afaik. I know one way to prevent
this is to acquire a write lock at the beginning, but how can you do that
with an index_read? It seems the only way to do that would be to read the
object then wread() it again with the object's primary key. Blech. Hopefully
there is some other solution?

Actually, after reading Ulf's reply, I just realized what I typed is
probably answered by what he said. Do you mean ALL locks are acquired before
any records are read or written? So in other words, the situation above is
impossible?

On Sun, Apr 5, 2009 at 3:27 AM, Ulf Wiger
<>wrote:

> Hynek Vychodil wrote:
>
>> mnesia uses optimistic locking. When NodeB's write is called than
>> transaction fails and is restarted. This is why mneasia transaction should
>> not contain side-effects. See mnesia manual for details.
>>
>
> Actually, no. Mnesia waits for the locks needed before
> proceeding, and keeps the locks until it either aborts
> or commits. However, in any locking environment, one
> must guard against deadlocks. If the lock manager is
> centralized, it's possible to maintain a wait-for graph,
> which is scanned each time a new lock is requested.
>
> This approach doesn't scale in a distributed setting,
> so an alternative approach, called "deadlock prevention",
> is to allow only unidirectional dependencies (for some
> definition of unidirectional - e.g. from smaller to
> larger pids.) If a lock is requested that would create
> a dependency in the other direction, one of the
> transactions involved is restarted. This is why mnesia
> transactions can restart sometimes.
>
> BR,
> Ulf W
> --
> Ulf Wiger
> CTO, Erlang Training & Consulting Ltd
> http://www.erlang-consulting.com
>




More information about the erlang-questions mailing list