[erlang-questions] Some mnesia oddity

Dan Gudmundsson dgud@REDACTED
Mon Oct 6 09:32:31 CEST 2008


You should be able to read the table in the same transaction,
but there is a bug in mnesia handling the special atom '_'.

delete_object is not match delete do you have records with '_' in them??

/Dan

Ben Hood wrote:
> Hi,
> 
> I know this is an old thread but I was wondering where the behaviour I
> am seeing is in any way related to passing in a pattern to
> mnesia:delete_object/1.
> 
> On Fri, Aug 29, 2008 at 12:20 PM, Dan Gudmundsson <dgud@REDACTED> wrote:
>>>      We found a strange mnesia behavior here...
>>>
>>>     Some mnesia:write operations after a mnesia:delete_object seem to
>>>     not have the expected result when executed in the same transaction.
>>>
>>>     See attached example file:
>>>     1 - We fill a test_table
>>>     2 - In the same transaction, we read all records, delete them, and
>>>     write them back (do not ask why :))
>>>     3 - Surprise! Only a subset of them can be read afterwards
>>>
>>>     Same result in R11 and R12.
>>>
>>>     It works if the delete_object and write operations are in separate
>>>     transactions... But who knows what can happen between them...
> 
> The code I am using (attached below) is similar to the above scenario.
> 
> Basically what I want to know is if there is a way to delete records
> from a table and then re-read the table in the same transaction, or
> whether this must be in separate transactions.
> 
> My use case is a densely populated table that I want to
> 
> 1. Selectively delete some records for;
> 2. Conditionally delete records from a different table if they no
> longer have any references in the first table.
> 
> So my approach could be characterized by a delete and sweep action.
> 
> Of course I could implement this functionality manually by re-reading
> the table and filtering out any results that I know will get deleted
> when the transaction commits. But if I could get mnesia to do this, it
> would be more elegant.
> 
> Also, I could do this in two transactions and re-arrange the code so
> to introduce something idempotent to get around the non-atomicity.
> 
> But if this could be solved using mnesia, that would be cool :-)
> 
> Thx,
> 
> Ben
> 
> ---snip---
> 
> -module(sync_test).
> 
> -compile(export_all).
> 
> -record(outer,{inner, const = const}).
> -record(inner,{a,b,c}).
> 
> init() ->
>     mnesia:start(),
>     mnesia:delete_table(outer),
>     {atomic,ok} = mnesia:create_table(outer,
>                         [{type,ordered_set},
>                          {attributes, record_info(fields, outer)}]),
>     ok.
> 
> insert() ->
>     Record = #outer{inner = #inner{a = 1, b = 2, c = now()}},
>     mnesia:transaction(fun() -> mnesia:write(Record) end).
> 
> one_tx() ->
>     Record = #outer{inner = #inner{a = 1, b = 2, c = '_'}},
>     mnesia:sync_transaction(
>         fun() ->
>             mnesia:delete_object(Record),
>             io:format("~p~n",[mnesia:match_object(Record)])
>         end).
> 
> two_tx() ->
>     Record = #outer{inner = #inner{a = 1, b = 2, c = '_'}},
>     mnesia:sync_transaction(
>         fun() ->
>             mnesia:delete_object(Record)
>         end),
>     mnesia:sync_transaction(
>         fun() ->
>             io:format("~p~n",[mnesia:match_object(Record)])
>         end).
> 



More information about the erlang-questions mailing list