erlang global:trans/4函數

根據erlang文檔node

trans(Id, Fun, Nodes, Retries) -> Res | abortedapp

Sets a lock on Id (using set_lock/3). If this succeeds, Fun() is evaluated and the result Res is returned. Returns aborted if the lock attempt fails. If Retries is set to infinity, the transaction does not abort.less

infinity is the default setting and is used if no value is specified for Retries.dom

set_lock(Id, Nodes, Retries) -> boolean()函數

Sets a lock on the specified nodes (or on all nodes if none are specified) on ResourceId for LockRequesterId. If a lock already exists on ResourceId for another requester than LockRequesterId, and Retries is not equal to 0, the process sleeps for a while and tries to execute the action later. When Retries attempts have been made, false is returned, otherwise true. If Retries is infinity, true is eventually returned (unless the lock is never released).this

If no value for Retries is specified, infinity is used.lua

This function is completely synchronous.code

If a process that holds a lock dies, or the node goes down, the locks held by the process are deleted.server

The global name server keeps track of all processes sharing the same lock, that is, if two processes set the same lock, both processes must delete the lock.ci

This function does not address the problem of a deadlock. A deadlock can never occur as long as processes only lock one resource at a time. A deadlock can occur if some processes try to lock two or more resources. It is up to the application to detect and rectify a deadlock.

能夠看到trans/4函數中,Id就是要加鎖的變量,Nodes就是參與加鎖的全部節點,Fun就是加鎖成功後要執行的函數,Retries就是加鎖操做失敗後重試的次數。 下面是trans/4函數的源碼:

trans(Id, Fun, Nodes, Retries) ->
    case set_lock(Id, Nodes, Retries) of
	true ->
            try 
                Fun()
            after
                del_lock(Id, Nodes)
            end;
	false ->
	    aborted
    end.

set_lock(Id, Nodes, Retries) when is_integer(Retries), Retries >= 0 ->
    set_lock(Id, Nodes, Retries, 1);
set_lock(Id, Nodes, infinity) ->
    set_lock(Id, Nodes, infinity, 1).

set_lock({_ResourceId, _LockRequesterId}, [], _Retries, _Times) ->
    true;
set_lock({_ResourceId, _LockRequesterId} = Id, Nodes, Retries, Times) ->
    ?trace({set_lock,{me,self()},Id,{nodes,Nodes},
            {retries,Retries}, {times,Times}}),
    case set_lock_on_nodes(Id, Nodes) of
	true -> 
            ?trace({set_lock_true, Id}),
            true;
        false=Reply when Retries =:= 0 ->
            Reply;
	false ->
	    random_sleep(Times),
	    set_lock(Id, Nodes, dec(Retries), Times+1)
    end.
dec(infinity) -> infinity;
dec(N) -> N - 1.
相關文章
相關標籤/搜索