Insert a record into Mnesia only if its key doesn't exist yet

I want to insert a record into a Mnesia table only when it doesn’t exist yet avoiding race conditions: if two processes try to add the same key only one should succeed.

There is the mnesia:wread/1 function which is just a shortcut for mnesia:read/2 with a write lock set on the record. The documentation says locks are on a record, but what if there is no record? Is the lock actually on the key? Would the below code work and achieve what I described above?

insert_if_not_exists(Record=#my_record{key=Key}) ->
       Fun = fun() ->
                 case mnesia:wread({my_record, Key}) of
                     [] -> % Key doesn't exist yet
                         mnesia:write(Record);
                     [_Existing] -> % Key exists
                         already_exists
                 end
             end,
       mnesia:transaction(Fun).
1 Like

It looks like the lock is on the tab and key

1 Like

Scanning mnesia code seems to indicate there is no check for the key existing before the lock is added, so it appears it should be safe.

1 Like