整了段代码,想用mnesia数据库来实现类似于Oracle中sequence 的功能。
原代码如下:
%% Author: Administrator %% Created: 2012-2-16 %% Description: TODO: Add description to id_generator -module(id_generator). -behavior(gen_server). %% %% Include files %% %% %% Exported Functions %% -export([start_link/0,getnewid/1]). -export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]). -record(ids,{idtype,ids}). -record(state,{}). %% %% API Functions %% start_link()-> gen_server:start_link({local,?MODULE}, ?MODULE, [],[]) . init([])-> mnesia:start(), io:format("Started"), mnesia:create_schema([node()]), case mnesia:create_table(ids,[{type,ordered_set}, {attributes,record_info(fields,ids)}, {disc_copies,[]} ]) of {atomic,ok}-> {atomic,ok}; {error,Reason}-> io:format("create table error") end, {ok,#state{}} . getnewid(IdType)-> io:format("waiting ~n"), %case mnesia:wait_for_tables([tbl_clientid], 5000) of % ok-> % gen_server:call(?MODULE, {getid,IdType}); % {timeout,_BadList}-> % {timeout,_BadList}; % {error,Reason}-> % {error,Reason} %end mnesia:force_load_table(ids), gen_server:call(?MODULE, {getid,IdType}) . %%generate new Id with given type handle_call({getid,IdType},From,State)-> F=fun()-> Result=mnesia:read(ids,IdType,write), case Result of [S]-> io:format("have ~n"), Id=S#ids.ids, NewClumn=S#ids{ids=Id+1}, mnesia:write(ids,NewClumn,write), Id; []-> io:format("none ~n"), NewClumn=#ids{idtype=IdType,ids=2}, mnesia:write(ids,NewClumn,write), 1 end end, case mnesia:transaction(F)of {atomic,Id}-> {atomic,Id}; {aborted,Reason}-> io:format("run transaction error ~1000.p ~n",[Reason]), Id=0; _Els-> Id=1000 end, {reply,Id,State} . handle_cast(_From,State)-> ok. handle_info(_From,State)-> ok. terminate(_From,State)-> ok. code_change(_OldVer,State,Ext)-> {ok,State}. %% %% Local Functions %%
使用方法:
id_generator:start_link().
id_generator:getnewid(aaa).
总结:
1.要注意将mnsia创建表时的参数写对
2.直接将表的列定义为一个record ,并且第二个字段与表同名
3.表未创建成功,或者有问题时mnesia:wait_for_tables 会超时,最好不要用mnesia:wait_for_tables([mytable],infinity),一旦出错快速结束很重要
4.针对可能异常的地方多判断,做好异常处理