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)。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。