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

mnesia的普通transaction写过程(三)锁请求

上一篇博文介绍了mnesia的写操作函数write完成的工作,其中涉及了锁请求过程,此后将继续分析。


mnesia_locker.erl

wlock(Tid, Store, Oid) ->

? ? wlock(Tid, Store, Oid, _CheckMajority = true).

wlock(Tid, Store, Oid, CheckMajority) ->

? ? {Tab, Key} = Oid,

? ? case need_lock(Store, Tab, Key, write) of

yes ->

? ?{Ns, Majority} = w_nodes(Tab),

? ?if CheckMajority ->

? ?check_majority(Majority, Tab, Ns);

? ? ? true ->

? ?ignore

? ?end,

? ?Op = {self(), {write, Tid, Oid}},

? ??ets_insert(Store, {{locks, Tab, Key}, write}),

? ?get_wlocks_on_nodes(Ns, Ns, Store, Op, Oid);

no when Key /= ?ALL, Tab /= ?GLOBAL ->

? ?[];

no ->

? ?element(2, w_nodes(Tab))

? ? end.

首先检查是否需要对要写的记录上锁。
need_lock(Store, Tab, Key, LockPattern) ->
? ? TabL = ?ets_match_object(Store, {{locks, Tab, ?ALL}, LockPattern}),
? ? if
TabL == [] ->
? ?KeyL = ?ets_match_object(Store, {{locks, Tab, Key}, LockPattern}),
? ?if
KeyL == [] ->?yes;
true ?->?no
? ?end;
true ->?no
? ? end.
检查过程仅仅是检查临时ets表内是否对记录上了行锁或表锁。
w_nodes(Tab) ->
? ? case ?catch_val({Tab, where_to_wlock}) of
{[_ | _], _} = Where -> Where;
_ -> ?mnesia:abort({no_exists, Tab})
? ? end.
mnesia使用ets表mnesia_gvars缓存了mnesia的全局变量和表的各项属性,相当于数据字典,此处从该表中取得数据表的where_to_wlock属性,以得到写该表时应该向哪些结点请求写锁。
该属性等同于表的where_to_write属性,在mnesia启动时进行表加载时、有结点加入该集群并创建表副本时、有结点退出该集群时等条件下进行修改,是一个动态值,等同于表的活动副本结点,包括其在线的所有ram_copies、d