transaction(Fun) -> t_result(Res)
transaction(Fun, Retries) -> t_result(Res)
transaction(Fun, Args :: [Arg :: term()]) -> t_result(Res)
transaction(Fun, Args :: [Arg :: term()], Retries) ->
t_result(Res)
Fun = fun((...) -> Res)
Retries = integer() >= 0 | infinity
将带有参数 Args
的函数对象 Fun
作为事务执行。
事务内部执行的代码可以由一系列表操作函数组成。如果由于用户错误或某个表不可用而导致事务内部出现问题,则整个事务将终止,并且函数 transaction/1
返回元组 {aborted, Reason}
。
如果一切顺利,则返回 {atomic, ResultOfFun}
,其中 ResultOfFun
是 Fun
中最后一个表达式的值。
如果存在结构 {family, Father, Mother, ChildrenList}
,则向数据库添加族的函数可以编写如下:
add_family({family, F, M, Children}) ->
ChildOids = lists:map(fun oid/1, Children),
Trans = fun() ->
mnesia:write(F#person{children = ChildOids}),
mnesia:write(M#person{children = ChildOids}),
Write = fun(Child) -> mnesia:write(Child) end,
lists:foreach(Write, Children)
end,
mnesia:transaction(Trans).
oid(Rec) -> {element(1, Rec), element(2, Rec)}.
此代码将一组人员添加到数据库中。在一个事务中运行此代码可确保将整个系列添加到数据库中,或者整个事务终止。例如,如果最后一个子文件格式错误,或者执行进程在执行系列代码时由于 'EXIT'
信号而终止,则事务将终止。因此,绝对不可能出现增加半个家庭的情况。
如果多个进程同时更新相同的记录,那么在事务中更新数据库也很有用。例如,函数raise(Name, Amount)
将Amount
添加到一个人的工资字段中,实现如下:
raise(Name, Amount) ->
mnesia:transaction(fun() ->
case mnesia:wread({person, Name}) of
[P] ->
Salary = Amount + P#person.salary,
P2 = P#person{salary = Salary},
mnesia:write(P2);
_ ->
mnesia:abort("No such person")
end
end).
当此函数在事务内执行时,运行在不同节点上的多个进程可以同时执行函数raise/2
,而不会互相干扰。
由于 Mnesia 检测到死锁,事务可以重新启动任意次数,因此 Fun
不应有任何副作用,例如等待特定消息。此函数尝试重新启动的次数与 Retries
中指定的次数相同。 Retries
必须是大于 0 的整数或原子 infinity
,默认为 infinity
。 Mnesia 使用 exit
异常来表示事务需要重新启动,因此 Fun
不得以 {aborted, term()}
为原因捕获 exit
异常。
相关用法
- erlang transcode(URIString, Options)用法及代码示例
- erlang trace_pattern(MFA :: send, MatchSpec, FlagList :: [])用法及代码示例
- erlang trace_pattern(MFA :: 'receive', MatchSpec, FlagList :: [])用法及代码示例
- erlang traverse(Name, Fun)用法及代码示例
- erlang trunc(Number)用法及代码示例
- erlang trim(String)用法及代码示例
- erlang tan用法及代码示例
- erlang tuple_to_list用法及代码示例
- erlang term_to_binary用法及代码示例
- erlang table(Table)用法及代码示例
- erlang term_to_binary(Term)用法及代码示例
- erlang throw(Any)用法及代码示例
- erlang time()用法及代码示例
- erlang timestamp()用法及代码示例
- erlang tl(List)用法及代码示例
- erlang tuple_size(Tuple)用法及代码示例
- erlang tuple_to_list(Tuple)用法及代码示例
- erlang to_list(Q :: queue(Item))用法及代码示例
- erlang take(Key, Orddict)用法及代码示例
- erlang table(Name)用法及代码示例
- erlang take(Key, Map1)用法及代码示例
- erlang to_list(MapOrIterator)用法及代码示例
- erlang take(String, Characters)用法及代码示例
- erlang titlecase(String :: unicode:chardata())用法及代码示例
- erlang to_float(String)用法及代码示例
注:本文由纯净天空筛选整理自erlang.org大神的英文原创作品 transaction(Fun) -> t_result(Res)。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。