[erlang-questions] mnesia:dirty_update_counter

Sébastien Saint-Sevin <>
Tue Mar 6 12:30:41 CET 2007


Hi Dan,

I've isolated the portion of code where the error occurs. Here is a test code.

%% file test.erl
-module(test).
-export([create_db/0]).

-record(counter, {
	  key,
	  value}).

create_db() ->
     Nodes = [node()],
     mnesia:stop(),
     mnesia:delete_schema(Nodes),
     mnesia:create_schema(Nodes),
     mnesia:start(),
     mnesia:create_table(counter,
			[{disc_copies, Nodes},
			 {attributes, record_info(fields, counter)}]),
     Id1 = mnesia:dirty_update_counter(counter, client, 1),
     io:format("ID1 : ~w~n", [Id1]),
     Id2 = mnesia:dirty_update_counter(counter, client, 1),
     io:format("ID2 : ~w~n", [Id2]),
     mnesia:stop().
%% end of file


Then a session :

erl -sname test

Eshell V5.5.3  (abort with ^G)
()1> cd("d:/dev/test").
d:/dev/test
ok
()2> c(test).
{ok,test}
()3> test:create_db().
ID1 : 1
ID2 : 2

=INFO REPORT==== 6-Mar-2007::12:26:06 ===
     application: mnesia
     exited: stopped
     type: temporary
stopped
()4> mnesia:start().
ok
()5> ets:i(counter).
<1   > {counter,client,1}
EOT  (q)uit (p)Digits (k)ill /Regexp -->q
quit
()6>


The counter table is finally populated with the (n-1) value of client ID where it sould be (n).
Hope this helps to clarify a bit the context.

Sébastien.


Dan Gudmundsson a écrit :
> 
> Hi
> 
> This works for me, what are you doing ?
> 
> 
> 1> mnesia:start().
> ok
> 2> mnesia:create_table(a, []).
> {atomic,ok}
> 3> mnesia:dirty_update_counter(a,1).
> ** exited: {aborted,{bad_type,a}} **
> 4> mnesia:dirty_update_counter(a,1,2).
> 2
> 5> ets:i(a).
> <1   > {a,1,2}
> EOT  (q)uit (p)Digits (k)ill /Regexp -->q
> quit
> 6> mnesia:dirty_update_counter(a,2,1).
> 1
> 7> ets:i(a).
> <1   > {a,2,1}
> <2   > {a,1,2}
> EOT  (q)uit (p)Digits (k)ill /Regexp -->q
> quit
> 
> 
> /Dan
> 
> 
> Sébastien Saint-Sevin wrote:
>>> It definitely seems like a bug, but I think that's intended behavior
>>> for backwards compatibility.
>>
>> I'm not sure it was intended in the past, coz the returned value for 
>> use by the function caller is 1 while the stored value for future 
>> increment is 0, which means the next returned value will still be   1, 
>> not being incremented the second time (and so generating overriding 
>> updates in mnesia records in my case...)
>>
>> If it was intended, the doc should at least be updated to describe 
>> this behaviour.
>>
>> Right now, my own workaround is just to be sure to correctly 
>> initialize the counter table with some value (0 is ok) before calling 
>> dirty_update_counter for the first time.
>>
>> Cheers,
>>
>> Sébastien.
>>
>>> Here's what we do, which seems to work:
>>>
>>>    case mnesia:dirty_update_counter(Db, Key, Inc) of
>>>     X when X == Inc ->
>>>         F = fun () ->
>>>             [R] = mnesia:read(Db, Key, write),
>>>             mnesia:write(R)
>>>         end,
>>>         mnesia:transaction(F);
>>>     _ ->
>>>         ok
>>>    end.
>>>
>>> On 3/5/07, Sébastien Saint-Sevin <> wrote:
>>>> Hi list,
>>>>
>>>> It seems I've found a bug regarding mnesia:dirty_update_counter(Tab, 
>>>> Key, Incr).
>>>> When I use the function for the first time with an Incr of 1 (Key 
>>>> not existing), the table is populated with a value of 0 for the key 
>>>> Key (1 expected) and returns 1 for NewVal (as expected).
>>>> The doc says : "If Key don't exits, a new record is created with the 
>>>> value Incr if it is larger than 0, otherwise it is set to 0."
>>>>
>>>> Is this confirmed or did I missed something ?
>>>>
>>>> Cheers,
>>>> Sébastien.
>>>>
>>>> PS : erl-5.5.3 under windows XP
>>>> _______________________________________________
>>>> erlang-questions mailing list
>>>> 
>>>> http://www.erlang.org/mailman/listinfo/erlang-questions
>>>>
>> _______________________________________________
>> erlang-questions mailing list
>> 
>> http://www.erlang.org/mailman/listinfo/erlang-questions
>>
> 
> 



More information about the erlang-questions mailing list