mnesia:clear_table

Ulf Wiger (AL/EAB) <>
Tue Aug 16 09:15:11 CEST 2005



mnesia:clear_table/1 calls mnesia_schema:clear_table/1,
which in its turn does the following:

clear_table(Tab) ->
  schema_transaction(fun() -> do_clear_table(Tab) end).


Schema transactions don't support nesting... or you could 
possibly have a schema transaction at the top and nest
regular transactions in it(*), but as mnesia_schema:do_clear_table/1
is not exported, you'll have a hard time doing even that.


(*) There may be serious issues with this - I can't say.


If you really, really want to do this, and don't want to 
hack mnesia so as to export do_clear_table/1, you can 
emulate it easily enough. This is how it's implemented:

do_clear_table(schema) ->
    mnesia:abort({bad_type, schema});
do_clear_table(Tab) ->
    TidTs = get_tid_ts_and_lock(schema, write),
    get_tid_ts_and_lock(Tab, write),
    insert_schema_ops(TidTs, make_clear_table(Tab)).

make_clear_table(Tab) ->
    ensure_writable(schema),
    Cs = val({Tab, cstruct}),
    ensure_active(Cs),
    ensure_writable(Tab),
    [{op, clear_table, cs2list(Cs)}].

The functions that are not exported from mnesia_schema are:
- do_clear_table/1
- make_clear_table/1
- ensure_writable/1

ensure_writable/1 looks like this:

ensure_writable(Tab) ->
    case val({Tab, where_to_write}) of
        [] -> mnesia:abort({read_only, Tab});
        _ -> ok
    end.


So, you can copy the code for ensure_writable/1 and 
make_clear_table/1. Then, your code becomes:

my_do_clear_table(schema) ->
   mnesia:abort({bad_type, schema});
my_do_clear_table(Tab) ->
   TidTs = mnesia_schema:get_tid_ts_and_lock(schema, write),
   mnesia_schema:get_tid_ts_and_lock(Tab, write),
   mnesia_schema:insert_schema_ops(TidTs, my_make_clear_table(Tab)).

my_make_clear_table(Tab) ->
    my_ensure_writable(schema),
    Cs = mnesia_lib:val({Tab, cstruct}),
    mnesia_schema:ensure_active(Cs),
    my_ensure_writable(Tab),
    [{op, clear_table, mnesia_schema:cs2list(Cs)}].

my_ensure_writable(Tab) ->
    case mnesia_lib:val({Tab, where_to_write}) of
        [] -> mnesia:abort({read_only, Tab});
        _ -> ok
    end.


Then you can combine this with other ops inside a 
top-level schema_transaction (important!)


()6> mnesia:create_table(test, [{ram_copies, [node()]}]).
{atomic,ok}
()7> mnesia:create_table(test1, [{ram_copies,[node()]}]).
{atomic,ok}
()8> mnesia:dirty_write({test,a,1}).
ok
()9> mnesia:dirty_write({test1,a,1}).
ok
()11> mnesia_schema:schema_transaction(fun() -> cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), mnesia:write({test,b,1}), mnesia:write({test1,b,1}) end).
{atomic,ok}
()12> ets:tab2list(test).
[{test,b,1}]
()13> mnesia_schema:schema_transaction(fun() -> cleart:my_do_clear_table(test), cleart:my_do_clear_table(test1), mnesia:transaction(fun() -> mnesia:write({test,b,1}), mnesia:write({test1,b,1}) end) end).
{atomic,{atomic,ok}}
()14> ets:tab2list(test).                                             [{test,b,1}]                                                                    



mnesia_schema:schema_transaction(
   fun() ->
       my_clear_table(Tab),
       mnesia:transaction(fun() -> 
                             ...
                          end)).

(:

/Uffe

> -----Original Message-----
> From: 
> [mailto:]On Behalf Of Serge Aleynikov
> Sent: den 16 augusti 2005 03:10
> To: Claes Wikstrom
> Cc: Erlang Questions
> Subject: Re: mnesia:clear_table
> 
> 
> Indeed when I do:
> 
> F = fun() ->
>          mnesia:clear_table(Tab)
>      end,
> mnesia:transaction(F).
> 
> It works.  That means that nested transactions are supported, however 
> this code returns an error:
> 
> p>erl -sname t
> Erlang (BEAM) emulator version 5.4.8 [source] [hipe] [threads:0]
> Eshell V5.4.8  (abort with ^G)
> ()1> mnesia:create_schema([node()]).
> ok
> ()2> mnesia:start().
> ok
> ()3> mnesia:create_table(test, [{ram_copies, [node()]}]).
> {atomic,ok}
> ()4> mnesia:create_table(test1, [{ram_copies, 
> [node()]}]). 
> 
> {atomic,ok}
> ()5> F = fun() -> mnesia:clear_table(test), 
> mnesia:clear_table(test1) end.
> #Fun<erl_eval.20.102880425>
> ()6> mnesia:transaction(F). 
> 
> {atomic,{aborted,nested_transaction}}
> 
> Am I doing something unconventional, or there is a limit on 
> the depth of 
> nested transactions?
> 
> Serge
> 
> Claes Wikstrom wrote:
> > Serge Aleynikov wrote:
> > 
> >> Hi,
> >>
> >> I am wondering why the mnesia:clear_table/1 function is 
> encapsulated 
> >> in a transaction of its own.  It prevents this function to 
> be included 
> >> in another transaction.
> >>
> > 
> > Transactions can be nested arbitrarily deep. Nesting doesn't
> > come for free, but it works.
> > 
> > 
> > /klacke
> > 
> 
> -- 
> Serge Aleynikov
> R&D Telecom, IDT Corp.
> Tel: (973) 438-3436
> Fax: (973) 438-1464
> 
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cleart.erl
Type: application/octet-stream
Size: 982 bytes
Desc: cleart.erl
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20050816/1a885a1b/attachment.obj>


More information about the erlang-questions mailing list