读书人

mnesia的普普通通transaction写过程(

发布时间: 2012-07-03 13:37:43 作者: rapoo

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)?ofdo_commit ->? ? ? ? ? ? {atomic, Result};? ? ? ? do_commit_nested ->? ? ? ? ? ? {nested_atomic, Result};? ? ? ? {do_abort, {aborted, Reason}} ->? ? ? ? ? ? {'EXIT', {aborted, Reason}};? ? ? ? {do_abort, Reason} ->? ? ? ? ? ? {'EXIT', {aborted, Reason}}? ? end.mnesia.erlwrite(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) ofets -> ? ??ets_insert(Tab, Val), ? ?ok;tid -> ? ?Store = Ts#tidstore.store, ? ?Oid = {Tab, element(2, Val)}, ? ?case LockKind ofwrite -> ? ?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 ofbag -> ? ??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上下文中时,需要向所有副本结点请求锁,请求到锁之后,需要把更新内容写入临时表。未完待续...

读书人网 >其他数据库

热点推荐