mnesia的普通transaction写过程(二)写操作

上一篇博文介绍了mnesia的事务准备阶段,在其transaction上下文中执行了传入的函数,该函数为

fun() -> mnesia:write({user, me, 12345}) end

此后将继续分析。

mnesia_tm.erl

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.
mnesia.erl
write(Val) when is_tuple(Val), tuple_size(Val) > 2 ->
    Tab = element(1, Val),
write(Tab, Val, write);
write(Tab, Val, LockKind) ->
    case get(mnesia_activity_state) of
{?DEFAULT_ACCESS, Tid, Ts} ->
   write(Tid, Ts, Tab, Val, LockKind);
{Mod, Tid, Ts} ->
   Mod:write(Tid, Ts, Tab, Val, LockKind);
_ ->
   abort(no_transaction)
    end.
之前已由mnesia_tm:execute_outer在进程字典内记录了事务上下文信息,此处在mnesia:write内重新取回,若无法取得,则表明mnesia:write未处于某个上下文中,将中止写操作。
write(Tid, Ts, Tab, Val, LockKind)
  when is_atom(Tab), Tab /= schema, is_tuple(Val), tuple_size(Val) > 2 ->
    case element(1, Tid) of
ets ->
   ?ets_insert(Tab, Val),
   ok;
tid ->
   Store = Ts#tidstore.store,
   Oid = {Tab, element(2, Val)},
   case LockKind of
write ->
   mnesia_locker:wlock(Tid, Store, Oid); %%----------->下一章 锁请求过程
sticky_write ->
   mnesia_locker:sticky_wlock(Tid, Store, Oid);
_ ->
   abort({bad_type, Tab, LockKind})
   end,
   write_to_store(Tab, Store, Oid, Val);
Protocol ->
   do_dirty_write(Protocol, Tab, Val)
    end;
此处Store为事务管理器创建的临时ets表,Oid为{表名,键名},将来会频繁用到。事务写要求mnesia向所有副本结点请求锁,因此需要一次全局锁请求广播,锁请求过程将在下一章中进行分析,此处先分析请求到锁的情形。
一旦获得锁,mnesia需要进行临时数据存储过程,将数据写入临时ets表中。
write_to_store(Tab, Store, Oid, Val) ->
    case ?catch_val({Tab, record_validation}) of
{RecName, Arity, Type}
 when tuple_size(Val) == Arity, RecName == element(1, Val) ->
   case Type of
bag ->
   ?ets_insert(Store, {Oid, Val, write});
_  ->
   ?ets_delete(Store, Oid),
   ?ets_insert(Store, {Oid, Val, write})
   end,
   ok;
{'EXIT', _} ->
   abort({no_exists, Tab});
_ ->
   abort({bad_type, Val})
    end.
write_to_store以一种不同的方式记录了数据的更新方式,即在临时表中记录{{Tab, Key}, Val, write}这样的内容,临时完成写操作。
mnesia:write将首先检查是否处于某个访问上下文中,当发现位于transaction上下文中时,需要向所有副本结点请求锁,请求到锁之后,需要把更新内容写入临时表。
未完待续...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值