Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You don't have to worry about it. From the mnesia documentation:</p> <blockquote> <p>Read locks may be shared, which means that if one transaction manages to acquire a read lock on an item, other transactions may also acquire a read lock on the same item. However, if someone has a read lock no one can acquire a write lock at the same item. If some one has a write lock no one can acquire a read lock nor a write lock at the same item.</p> </blockquote> <p>If a transaction has a read lock on an object, that object can't be edited by another transaction.</p> <p>Say you have two transactions, T1 and T2, which are executing in parallel:</p> <ol> <li>T1 does <code>mnesia:match_object</code>, and acquires a read lock on all the returned objects.</li> <li>T2 does an equivalent <code>mnesia:match_object</code>, and acquires a read lock on the same objects.</li> <li>T2 attempts to acquire a write lock on of the objects (to edit it).</li> <li>Mnesia automatically aborts T2, to be retried later.</li> <li>T1 acquires a write lock on the objects, and edits them.</li> <li>T1 finishes.</li> <li>Mnesia retries T2.</li> </ol> <p>Note that T2 may be retried several times, depending on how long T1 takes to complete (ie. release its locks).</p> <p>According to my tests, the locking behavior of <code>mnesia:match_object</code> isn't consistent. For example, <code>mnesia:match_object(mytable, {mytable, 2, '_'}, LockType)</code> will lock only the record with Key 2, but <code>mnesia:match_object(mytable, {mytable, '_', test}, LockType)</code> locks the entire table.</p> <p>Also note that the documentation isn't correct, <code>mnesia:match_object(Table, Pattern, write)</code> does work, and seems to follow the same pattern as 'read', ie. if you specify the key, only the matching record will be write-locked; if you don't specify the key, the entire table will be write-locked.</p> <p>You can test it yourself by doing something like this:</p> <pre><code>test() -&gt; mnesia:transaction(fun()-&gt; Table = mytable, Matches = mnesia:match_object(Table, {Table, 2, '_'}, write), io:format("matched: ~p~n", [Matches]), spawn(fun()-&gt;mnesia:transaction(fun()-&gt; io:format("trying to read~n",[]), io:format("read: ~p~n", [mnesia:read(Table, 2, read)]) end) end), timer:sleep(1000), RereadMatches = lists:map(fun(#mytable{id=Id}) -&gt; mnesia:read(Table, Id, write) end, Matches), io:format("reread matches: ~p~n", [RereadMatches]) end). </code></pre> <p>By changing the pattern and lock type passed to <code>match_object</code>, and the key number and lock type passed to <code>mnesia:read</code> in the spawned process (or by using <code>mnesia:write</code>), you can test the various locking behaviors.</p> <p><strong>Addendum:</strong> See this <a href="http://groups.google.com/group/erlang-programming/browse_thread/thread/820d4f7aaa46f768/d20e20924f756c41?lnk=gst#d20e20924f756c41" rel="nofollow noreferrer">post by Ulf Wiger</a> on the same topic.</p> <p><strong>Addendum 2:</strong> See the <a href="http://www.erlang.org/doc/apps/mnesia/Mnesia_chap4.html#id2270506" rel="nofollow noreferrer">section on "Isolation"</a> in the Mnesia user guide.</p> <p><strong>Edit:</strong> The above was all done on a set-type table, <code>match_object</code> locking behavior might be different on a bag-type table.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload