[erlang-questions] mnesia:dirty_update_counter and replicated tables

Ulf Wiger (TN/EAB) ulf.wiger@REDACTED
Thu Sep 21 18:11:47 CEST 2006


Even though this problem would seem to be addressed by 
wrapping dirty_update_counter inside a transaction:

mnesia:activity(
   transaction,
   fun() ->
      mnesia:write_lock_table(Tab),
      mnesia:dirty_update_counter({Tab, Key}, Incr)
   end).

It _still_ wouldn't be safe, for the following reasons:

- Dirty updates within a transaction are not recognized
  as updates per se. So there will be failure situations
  were the update may not propagate consistently to all
  replicas.
- Since the dirty update cannot be undone, and mnesia 
  reserves the right to re-run transactions in the name
  of deadlock prevention, you are not guaranteed that 
  the update will happen only once.
- If your transaction aborts, the update_counter will
  not be rolled back, if it had time to execute before
  the abort, which you have no way of knowing (unless
  you add some additional dirty stuff).

BR,
Ulf W
 
Serge Aleynikov wrote:
> 
> Scott,
> 
> The answer is regretfully no.  Let's consider an example to 
> illustrate this point.  You have two nodes A and B both 
> running mnesia with a replicated table.
> 
> 1. The content of a counter is 1.
> 2. Node A does a mnesia:dirty_update_counter call to 
> increment the value of the counter by 2.
> 3. Very closely in time node B does 
> mnesia:dirty_update_counter call to increment the counter by 3.
> 
> After this the value of that field could be either one of:
> 
> a) 3.
> b) 4.
> c) 6.
> 
> No guarantees can be made as to which value the counter would 
> hold without having cross-node locking involved by using transactions.
> 
> Depending on the application you could use transactions to 
> update data and dirty operations for read-only purposes.




More information about the erlang-questions mailing list