[erlang-questions] Some mnesia oddity

Ben Hood <>
Sun Oct 5 13:20:59 CEST 2008


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 <> 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