Inserting without overwriting with mnesia or ets

Hal Snyder <>
Sun May 9 01:29:49 CEST 2004


"Ulf Wiger (AL/EAB)" <> writes:

> The solution below is perhaps not fast, but it's generic.

Just to make sure I'm on the same page with you guys, let me rephrase
things a little. Feel free to correct if I missed something.

I guess the thread is about distributed atomic test-and-set. The
"generic approach" below is needlessly slow if

a. updates always happen on one node
b. replicas are kept on other nodes for reliability only

in which case you don't want the overhead of locking the replicas when
doing test-and-set.

A faster approach would be to take a process somewhere, give it a
table (mnesia or ets or hash) updated by no other process and put it
in a receive loop to provide ACID test-and-set to the rest of the
system. Or does some class of mnesia calls already provide the
aforesaid serialization?

Next comes a question about mnesia and dirty ops, which I think is
mostly answered by Ulf's previous reply: under what conditions is a
sequence of dirty reads and writes from a single process to a mnesia
table consistent, i.e. each read or write sees the table as if all
previous updates have completed in order, if no other process writes
to the table?

The answer seems to be:

a. table exists as ram_copy locally (+ .. ) as in next paragraph

b. remote tables too? Doesn't that get into questions of message ordering
   as discussed recently on this list?


> Iff you know that the table exists as a ram_copy locally (+ you know
> that the object cannot have been created earlier in the same
> transaction, in which case it would exist temporarily in another ets
> table - and that the object could not be in the process of being
> created in another simultaneous transaction, etc.), you can "cheat"
> and use ets:member/2, but you need to make sure you understand the
> implications of this, and determine whether it is safe to do so in
> _your_ case. Then you should highlight the code with comments
> reminding yourself that you've done something dirty.
>
> Given that some of the above conditions hold, you could check with
> mnesia:dirty_read/1, which works on all types of tables and even if
> the table is remote, but still has the same problems re. transaction
> safety.

...

[generic solution]

>> [mailto:]On Behalf Of Einar Karttunen
>> Sent: den 7 maj 2004 14:29
>> To: 
>> Subject: Inserting without overwriting with mnesia or ets

>> The naive approach is not very good:
>> 
>> insert(K,V) ->
>> 	fun() ->
>> 		case mnesia:wread(K) of
>> 		[Exist] -> {abort, Exist};
>> 		_ -> mnesia:write(V)
>> 		end
>> 	end.



More information about the erlang-questions mailing list