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