2016-10-19 105 views
1

ets doc,對單個對象的所有更新都保證是原子的和孤立的。這意味着對單個對象的更新操作要麼成功就要麼完全失敗(原子性),並且其他進程不能看到更新的中間結果(隔離)。Erlang ETS原子和分離

爲下面的代碼,我包兩個表爲一個

我的問題:

  1. 這是在二郎山一個共同的模式?

  2. 爲插入和更新,它是原子和孤立?

    -module(example_store)。 -export([init/0, insert/1, update/1])。

    的init() - > ETS:新的(存儲,[公衆, named_table, {read_concurrency,TRUE}, {write_concurrency,真}]),

    數據= ETS:新(store_data, [公衆, named_table, {read_concurrency,TRUE},{ write_concurrency,真}]),

    Info = ets:new(store_info, [public,ordered_set, 
         named_table, 
          {read_concurrency, true}, 
        {write_concurrency, true}]), 
    
    ets:insert(store, {store, Data, Info}). 
    
    
    %% insert data 
    insert({Key, Value, Info}) -> 
        {store, Data_tb, Info_tb} = ets:lookup(store, store), 
        ets:insert(Data_tb, {Key, Value}), 
        ets:insert(Info_tb, {Info, Key}), 
        ok. 
    
    
    %% update data 
    update({Key, Value, Info, Info_old}) -> 
        {store, Data_tb, Info_tb} = ets:lookup(store, store), 
        ets:insert(Data_tb, {Key, Value}), 
        ets:delete(Info_tb, {Info_old,Key}), 
        ets:insert(Info_tb, {Info, Key}), 
        ok. 
    

Update_1 來自@Derek Brown,包裹的表不能保證insert/1update/1被隔離。

問題3:是否有可能將它隔離? (除Gen_server外)

回答

1

1)不可以。使用named_table時從ets:new/2返回的名稱與您用於第一個參數的名稱相同。所以這就是你在store表中存儲的名字。因此,在insert/1update/1中,您可以直接使用store_datastore_info原子。

2)不,插入和更新既不是原子也不是孤立的。不是原子的,因爲那不是Erlang函數的功能。比方說,如果insert/1中的第一個ets:insert/2呼叫成功了,但第二個呼叫由於某種原因失敗了,那麼第一個沒有任何類型的自動回滾。而不是孤立的,因爲不能保證給定的函數(例如,insert/1update/1)將以原子方式執行。其他進程可以在您的功能完成之前看到中間效果。

+0

除了gen_server之外,有沒有一種方法可以保證'update'被隔離? – user3644708