2013-08-02 2 views

ответ

2

Самый простой способ это выполняет все тесты в одной транзакции Mnesia. следующий код делает это.

Помните, что этот код не проверяет, существует ли идентификатор, поэтому, если вы попытаетесь добавить нового пользователя с существующим идентификатором и новым идентификатором входа и электронной почтой, он просто перезапишет существующую запись (то есть поведение задавать).

%% record declaration 
-record (cuser, {id,login_id,email}), 
%% create a table for test 
mnesia:create_schema([node()]), 
application:start(mnesia), 
mnesia:create_table(cuser,[{attributes,record_info(fields,cuser)}, 
          {index,[#cuser.login_id,#cuser.email]}, 
          {disc_copies,[node()]}, 
          {type,set}]), 
%% write 2 record for test 
Wr = fun(I,L,E) -> mnesia:write(#cuser{id=I,login_id=L,email=E}) end, 
mnesia:transaction(Wr,[u1,l1,m1]), 
mnesia:transaction(Wr,[u2,l2,m2]), 
%% create a function for filtering 
M = fun(Nl,Ne) -> 
     Match = ets:fun2ms(fun(#cuser{id=I,login_id=Li,email=E}) when Li =:= Nl; E =:= Ne -> {I,Li,E} end), 
     mnesia:select(cuser,Match) 
    end, 
%% create a function to add a new user 
Add = fun(I,Nl,Ne) -> 
     {atomic,R} = mnesia:transaction(M,[Nl,Ne]), 
     case R of 
      [] -> mnesia:transaction(Wr,[I,Nl,Ne]); 
      R -> {already_exist,R} 
     end 
     end, 
%% add new user 
mnesia:transaction(Add,[i3,l3,m1]), %% will return {atomic,{already_exist,[{u1,l1,m1}]}} 
mnesia:transaction(Add,[i3,l3,m3]), %% will return {atomic,{atomic,ok}} 

Чтобы проверить, если Id уже существует, просто добавьте тест в функции фильтра:

%% create a function for filtering 
M = fun(Ni,Nl,Ne) -> 
     Match = ets:fun2ms(fun(#cuser{id=I,login_id=Li,email=E}) when I =:= Ni; Li =:= Nl; E =:= Ne -> {I,Li,E} end), 
     mnesia:select(cuser,Match) 
    end, 
%% create a function to add a new user 
Add = fun(I,Nl,Ne) -> 
     {atomic,R} = mnesia:transaction(M,[I,Nl,Ne]), 
     case R of 
      [] -> mnesia:transaction(Wr,[I,Nl,Ne]); 
      R -> {already_exist,R} 
     end 
     end, 
+0

спасибо за ваш ответ. У меня вопрос о синхронизации. Если два клиента одновременно отправляют запрос «добавить пользователя». один - [i4, l4, m4], а другой - [i5, l5, m4], каков результат? –

+0

вы не можете знать, какой из них выиграет, но только один пользователь должен быть записан, другой - уже has_exist. – Pascal

+0

так, только одна транзакция работает одновременно, не так ли? –

0

Mneisa является ключ-значение система хранения, которая гарантирует только ключ.

Единственный способ, которым я могу придумать, - использовать кортеж, чтобы сохранить {id, login_id} в качестве первичного ключа.

К сожалению, это может гарантировать только один из них является уникальным. Однако, по крайней мере, вы можете запросить элемент с помощью {id, login_id}.

Например:

-record(cuser, { 
    uid, %uid = {id, login_id} 
    email, 
    ....}). 
+0

может быть, это не хорошая производительность для выбора запроса –