Mnesia(7)

2019-01-12 11:40

数据的Erlang进程没有从隔离性中得到好处 脏操作的优点是它们比相应的事务处理快的多

如果脏操作处理disc_copies、disc_only_copies类型的表,则写到磁盘 如果脏写操作执行在这种表上,Mnesia也保证所有的表备份一起更新

脏操作将保证某种级别的一致性,例如脏操作不可能返回混乱的record,这样每个单独的读或写操作以一个原子的行为执行

所有的脏操作在失败时调用exit({aborted, Reason}),即使在事务中执行以下方法也不会获取锁:

Java代码

?? mnesia:dirty_read({Tab, Key}) ?? mnesia:dirty_write(Record) ?? mnesia:dirty_delete({Tab, Key}) ?? mnesia:dirty_delete_object(Record) ?? mnesia:dirty_first(Tab) ?? mnesia:dirty_next(Tab, Key) ?? mnesia:dirty_last(Tab) ?? mnesia:dirty_prev(Tab, Key) ?? mnesia:dirty_slot(Tab, Slot)

?? mnesia:dirty_update_counter({Tab, Key}, Val) ?? mnesia:dirty_match_object(Pat) ?? mnesia:dirty_select(Tab, Pat)

?? mnesia:dirty_index_match_oject(Pat, Pos) ?? mnesia:dirty_index_read(Tab, SecondaryKey, Pos) ?? mnesia:dirty_all_keys(Tab)

mnesia:dirty_read({Tab, Key}) mnesia:dirty_write(Record) mnesia:dirty_delete({Tab, Key}) mnesia:dirty_delete_object(Record) mnesia:dirty_first(Tab) mnesia:dirty_next(Tab, Key) mnesia:dirty_last(Tab) mnesia:dirty_prev(Tab, Key) mnesia:dirty_slot(Tab, Slot)

mnesia:dirty_update_counter({Tab, Key}, Val) mnesia:dirty_match_object(Pat) mnesia:dirty_select(Tab, Pat)

mnesia:dirty_index_match_oject(Pat, Pos) mnesia:dirty_index_read(Tab, SecondaryKey, Pos) mnesia:dirty_all_keys(Tab)

4,Record名与Table名

Mnesia里表的所有record必须有一样的名字,所有的record必须为相同record类型的实例 但是record名没有必要和table名一样

如果表创建时没有指定record_name属性,那么表里所有的record会有和表名一样的record名 如果多个表创建时指定了相同的record_name属性,那么相同名字的record可以存储在多个表中 访问这些指定了record_name的表时不能简单的使用mnesia:write/1和mnesia:s_write/1,而应该使用mnesia:write/3:

Java代码

?? mnesia:write(subscriber, #subscriber{}, write)

?? mnesia:write(my_subscriber, #subscriber{}, sticky_write) ?? mnesia:write(your_subscriber, #subscriber{}, write)

mnesia:write(subscriber, #subscriber{}, write)

mnesia:write(my_subscriber, #subscriber{}, sticky_write) mnesia:write(your_subscriber, #subscriber{}, write)

5,Activity概念和多种访问上下文

前面说到,mnesia:transaction/1,2,3的参数functional object(Fun)执行以下表操作:

Java代码

?? mnesia:write/3 (write/1, s write/1) ?? mnesia:delete/3 (delete/1, s delete/1)

?? mnesia:delete object/3 (delete object/1, s delete object/1) ?? mnesia:read/3 (read/1, wread/1) ?? mnesia:match object/2 (match object/1) ?? mnesia:select/3 (select/2)

?? mnesia:foldl/3 (foldl/4, foldr/3, foldr/4) ?? mnesia:all keys/1

?? mnesia:index match object/4 (index match object/2) ?? mnesia:index read/3

?? mnesia:lock/2 (read lock table/1, write lock table/1) ?? mnesia:table_info/2

mnesia:write/3 (write/1, s write/1) mnesia:delete/3 (delete/1, s delete/1)

mnesia:delete object/3 (delete object/1, s delete object/1) mnesia:read/3 (read/1, wread/1) mnesia:match object/2 (match object/1) mnesia:select/3 (select/2)

mnesia:foldl/3 (foldl/4, foldr/3, foldr/4) mnesia:all keys/1

mnesia:index match object/4 (index match object/2) mnesia:index read/3

mnesia:lock/2 (read lock table/1, write lock table/1) mnesia:table_info/2

这些操作将在一个涉及到锁、日志、备份、checkpoint、subscription、提交协议等等的事务上下文里执行

但是,这些方法也可以在其他activity上下文里执行 Mnesia支持以下activity访问上下文:

Java代码

?? transaction ?? sync_transaciton ?? async_dirty ?? sync_dirty ?? ets

transaction sync_transaciton async_dirty sync_dirty ets

Fun作为参数传给mnesia:sync_transaction(Fun, [,Args])时会在同步事务上下文里执行 同步事务等待所有活动备份提交事务到硬盘才返回

多于在多个节点上执行并且希望确定远程节点更新已被执行的应用,以及联合事务写和dirty_read的应用,sync_transaction特别有用

sync_transaction对于需要频繁和大量可能对其他节点的Mnesia负载过重的更新的应用也有用

6,嵌套事务 事务可以任意嵌套

一个子事务必须运行在和父亲相同的进程里

当子事务终止时,子事务的调用者会得到返回值{aborted, Reason}并且子事务执行的任何任务都会擦除

如果子事务提交,则子事务写入的record会传播到父事务 当子事务终止时不会释放锁

一个嵌套事务序列创建的锁会一直保持直到最顶端的事务终止 而且,嵌套事务所做的更新只传播到父亲可见 不到最顶端事务结束,不会做最终的提交

这样,即使一个嵌套的事务返回{atomic, Val},如果外层的父事务失败,那么嵌套子事务也失败 具有嵌套事务与顶级事务相同语义的能力会让写操作Mnesia表的库函数更容易

Java代码

?? add_subscriber(S) ->

?? mnesia:transaction(fun() -> ?? case mneisa:read( ......

add_subscriber(S) ->

mnesia:transaction(fun() -> case mneisa:read( ......

该方法需要作为一个事务来调用

现在假设我们希望写一个方法,该方法调用add_subscriber/1方法,并且本身由一个事务上下文保护

通过在另一个事务里简单的调用add_subscriber/1,则创建了一个嵌套事务

7,模式匹配

当不能使用mnesia:read/3方法时,Mnesia提供了一些方法来对record进行模式匹配:

Java代码

?? mnesia:select(Tab, MatchSpecification, LockKind) -> ?? transaction abort | [ObjectList]

?? mnesia:select(Tab, MatchSpecification, NObjects, Lock) -> ?? transaction abort | {[Object], COntinuation} | '$end_of_table' ?? mnesia:select(cont) ->

?? transaction abort | {[Object], COntinuation} | '$end_of_table' ?? mnesia:match_object(Tab, Pattern, LockKind) -> ?? transaction abort | RecordList

mnesia:select(Tab, MatchSpecification, LockKind) ->

transaction abort | [ObjectList]

mnesia:select(Tab, MatchSpecification, NObjects, Lock) -> transaction abort | {[Object], COntinuation} | '$end_of_table' mnesia:select(cont) ->

transaction abort | {[Object], COntinuation} | '$end_of_table' mnesia:match_object(Tab, Pattern, LockKind) -> transaction abort | RecordList

这些方法对Tab表的所有记录匹配一个Pattern

没有必要对整张表执行昂贵的搜索,通过使用索引和pattern的key的绑定值,该方法所做真正的工作可能压缩为一些哈希查询

如果key部分绑定,则使用ordered_set表可能减少搜索空间

Java代码

?? Pat = #employee{sex = female, _ = '_'}, ?? F = fun() -> mnesia:match_object(Pat) end, ?? Females = mnesia:transaction(F).

Pat = #employee{sex = female, _ = '_'}, F = fun() -> mnesia:match_object(Pat) end, Females = mnesia:transaction(F).

8,迭代

Mnesia提供一些方法来迭代表里的所有记录:

Java代码

?? mnesia:foldl(Fun, Acc0, Tab) -> NewAcc | transaction abort ?? mnesia:foldr(Fun, Acc0, Tab) -> NewAcc | transaction abort

?? mnesia:foldl(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort ?? mneisa:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort

mnesia:foldl(Fun, Acc0, Tab) -> NewAcc | transaction abort mnesia:foldr(Fun, Acc0, Tab) -> NewAcc | transaction abort

mnesia:foldl(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort mneisa:foldr(Fun, Acc0, Tab, LockType) -> NewAcc | transaction abort


Mnesia(7).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:基于单片机的数字电压表开题报告

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: