[erlang-questions] (not) understanding mnesia transactions

Seth Falcon <>
Thu Jun 18 15:57:31 CEST 2009


* On 2009-06-18 at 12:05 +0200 Dan Gudmundsson wrote:
> The problem here lies in how mnesia handles indexes and locks on indexes.
>
> If you remove the index the code works as expected.

I'll take working code over fast but wrong code :-)

But I'm thinking that adding the locking is the way to go since
without an index the look up is a full table scan.

> Except for io:format("Expecting ~p~n", [lists:seq(1, 10)]), which is wrong,
> since you use dirty_update_counter which will be invoked
> several times when there is a lock conflict on the write lock.

Oh, right.  Since I'm already going to lock the url table for the
index read and record write, perhaps there isn't much additional value
in using dirty_update_counter here?  If instead, I also locked the
counter table and did the counter increment "by hand", then repeated
calls due to failed transactions (lock conflict) would not lose
counter values.  Does that sound right?

> But back to the index lock problem.
>
> Whether you use qlc or index_read in that query the same code will be invoked.
>
> mnesia:index_read grabs a read lock on the rows it hits.
> In your case when 5 parallel processes read the index for "url-1"
> none is found, no locks are grabbed.
>
> You then generate a unique key for each process, and write the record down,
> that will succeed since they have unique keys.
>
> This is bug in mnesia, 12 years old :-(

Interesting.  I was surprised not to find a LockType option for
index_read after seeing the option for other read operations.  Anyhow,
thanks for the additional explanation.

+ seth


More information about the erlang-questions mailing list