日期:2014-05-16  浏览次数:20412 次

mnesia的普通transaction写过程(四)事务提交准备

上一篇博文介绍了mnesia的锁请求过程,在请求到锁后,mnesia:write将更新写入临时ets表,此后mnesia:write将完成其使命,重新回到mnesia_tm:apply_fun函数中,此后将继续分析。


apply_fun(Fun, Args, Type) ->

? ? Result = apply(Fun, Args),

? ? case t_commit(Type) of

do_commit ->

? ? ? ? ? ? {atomic, Result};

? ? ? ? do_commit_nested ->

? ? ? ? ? ? {nested_atomic, Result};

? ? ? ? {do_abort, {aborted, Reason}} ->

? ? ? ? ? ? {'EXIT', {aborted, Reason}};

? ? ? ? {do_abort, Reason} ->

? ? ? ? ? ? {'EXIT', {aborted, Reason}}

? ? end.

Type参数为async

t_commit(Type) ->

? ? {_Mod, Tid, Ts} = get(mnesia_activity_state),

? ? Store = Ts#tidstore.store,

? ? if

Ts#tidstore.level == 1 ->

? ?intercept_friends(Tid, Ts),

? ?%% N is number of updates

? ?case arrange(Tid, Store, Type) of

{N, Prep} when N > 0 ->

? ?multi_commit(Prep#prep.protocol,

majority_attr(Prep),

Tid, Prep#prep.records, Store);

{0, Prep} ->

? ?multi_commit(read_only,

majority_attr(Prep),

Tid, Prep#prep.records, Store)

? ?end;

...

? ? end.

在进行事务提交前,需要为每个事务参与结点计算其更新内容。

arrange(Tid, Store, Type) ->

? ? Nodes = get_elements(nodes,Store),

? ? Recs = prep_recs(Nodes, []),

? ? Key = ?ets_first(Store),

? ? N = 0,

? ? Prep =

case Type of

? ?async -> #prep{protocol = sym_trans, records = Recs};

? ?sync -> #prep{protocol = sync_sym_trans, records = Recs}

end,

? ? case catch do_arrange(Tid, Store, Key, Prep, N) of

{'EXIT', Reason} ->

? ?dbg_out("do_arrange failed ~p ~p~n", [Reason, Tid]),

?