[erlang-questions] mnesia transaction
Gleb Peregud
gleber.p@REDACTED
Mon Aug 3 23:20:28 CEST 2009
2009/8/3 paweł kamiński <kamiseq@REDACTED>:
> hej all,
> I tired to look for answers but all I got was about quering itslef and only
> highlighted that quering without transaction is very dangerous... :) (yeah
> tell me more)
>
> I have a question why my query in qlc cant be run without transaction??
>
> Q = qlc:q([C#client_map.rel_clientID || C <- mnesia:table(client_map),
> C#client_map.mtr_clientID == ClientID]),
> Read = fun()->
> qlc:e(Q)
> end,
> {atomic, List} = mnesia:transaction(Read),
> List.
>
> my first attempt was
> Q = qlc:q([C#client_map.rel_clientID || C <- mnesia:table(client_map),
> C#client_map.mtr_clientID == ClientID]),
> qlc:e(Q).
Probably qlc query could be run without transactions if you use
mnesia:activity/* with context async_dirty or sync_dirty or you could
use mnesia:async_dirty/1 or mnesia:sync_dirty/1, which, in fact, is
the same. I have never tried it, but it should work.
Please try this code:
Q = qlc:q([C#client_map.rel_clientID || C <- mnesia:table(client_map),
C#client_map.mtr_clientID == ClientID]),
mnesia:async_dirty(fun() -> qlc:e(Q) end).
> more questions :
> 1)can I select rows dirtily??
See mnesia:dirty_match_object/1 or preferably
mnesia:dirty_index_match_object/2,3. These should be optimal choice
for your use case.
mnesia:add_table_index(client_map, [rel_clientID]).
mnesia:dirty_index_match_object(#client_map{rel_clientID = Id, _ =
'_'}, rel_clientID).
Please note, according to the manual:
"The two index search functions described here are automatically
invoked when searching tables with qlc list comprehensions and also
when using the low level mnesia:[dirty_]match_object functions"
So you can use qlc in dirty context.
If you need more control you can try using mnesia:dirty_select/2.
> 2)is there a way to read snapshot of data while other processes are still
> writing to db, so transaction is no needed. I ve read in man that ther is
> fun activate_checkpoint/1 but can I run a query without transaction that
> will implicitly create such a checkpoint.??
Afaik transactions is the only way to archive this. I've tried the following:
node@REDACTED and othernode@REDACTED shares table "simple".
(node@REDACTED)> mnesia:activate_checkpoint([{name, test}, {max, [simple]}]).
(othernode@REDACTED)> mnesia:dirty_write(simple, {simple, a, 1}).
(node@REDACTED)> mnesia:dirty_all_keys(simple).
[a]
(node@REDACTED)> mnesia:dirty_read(simple, a).
[{simple,a,1}]
So checkpoints does not work for dirty operations. Please correct me
if my experiment is flawed.
> 3)then what is the difference between qlc and dirty_read, dirty_select or
> qlc is somehow compiled to dirty_* functions??
afaik, qlc is a query language, which is "compiled" down to the
appropriate functions [dirty_]read, [dirty_]select, etc. according to
the context. So your first code snippet is the same as running
mnesia:match_object in mnesia:transaction. My code for qlc in
async_dirty context is probably the same as running
mnesia:dirty_match_object.
> 4)what will exactly happened when I dirty_write to my table when 10 other
> processes are reading from it???
afaik other processes not using transactions will read or not written
changes - it depends on the timing and it is a source of race
conditions. If other processes use transactions they should be reading
consistent snapshot of data as it was before running dirty_write.
Please correct me if I'm wrong :)
>
> thanks
>
> pozdrawiam
> Paweł Kamiński
Również pozdrawiam,
Gleb Peregud
More information about the erlang-questions
mailing list