[erlang-questions] Mnesia transactions and locking

Ulf Wiger (TN/EAB) <>
Tue Jun 12 13:48:06 CEST 2007


 
Joel Reymont wrote:
> 
> How does Mnesia determine whether a record or a table
> needs to be locked in a transaction?
> 
> Please feel free to point me to the Mnesia code
> (which I'm still studying).

It acquires locks as it goes along, or when the user
specifically asks for a lock. When a transaction 
commits or aborts, all locks are automatically 
released.

To exemplify with mnesia:write/1 from mnesia.erl

write(Val) when tuple(Val), size(Val) > 2 -> 
    Tab = element(1, Val),
    write(Tab, Val, write);
...

write(Tid, Ts, Tab, Val, LockKind)
  when atom(Tab), Tab /= schema, tuple(Val), size(Val) > 2 ->
    case element(1, Tid) of
        ets ->
            ?ets_insert(Tab, Val),
            ok;
        tid ->
            Store = Ts#tidstore.store,
            Oid = {Tab, element(2, Val)},
            case LockKind of
                write ->
                    mnesia_locker:wlock(Tid, Store, Oid);
                sticky_write ->
                    mnesia_locker:sticky_wlock(Tid, Store, Oid);
                _ ->
                    abort({bad_type, Tab, LockKind})
            end,
            write_to_store(Tab, Store, Oid, Val);
        Protocol ->
            do_dirty_write(Protocol, Tab, Val)
    end;

So, mnesia checks the context (transaction, dirty or 
raw ets op), and acquires a lock if it's a transaction.

The locker will check whether a new lock is needed
and, if so, try to grab it. It put the transaction
in a wait list. There is a global ordering of 
transactions, and "newer" transactions are not 
allowed to wait for "older" transactions (not 
allowed to wait means that the transaction is 
restarted). This ensures that there will be no
circular waits, and thus no deadlocks.
(See mnesia_locker:can_lock/4.)

BR,
Ulf W



More information about the erlang-questions mailing list