[erlang-questions] Mnesia transactions and locking
Ulf Wiger (TN/EAB)
ulf.wiger@REDACTED
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