Erlang ETS原子和孤立

时间:2016-10-19 15:14:59

标签: erlang ets

来自ets doc对单个对象的所有更新都保证是原子的和隔离的。这意味着对单个对象的更新操作要么成功要么完全失败而没有任何影响(原子性),并且其他进程(隔离)不能看到更新的中间结果。

对于以下代码,我将两个表包装成一个

我的问题:

  1. 这是Erlang中常见的模式吗?

  2. 对于插入和更新,它是原子的还是隔离的?

    - 模(example_store)。 -export([INIT / 0,          插入/ 1,          更新/ 1])。

    init() - >   ets:new(商店,[公共,                  named_table,                  {read_concurrency,true},                  {write_concurrency,true}]),

    数据= ets:new(store_data,[public,                 named_table,                    {read_concurrency,true},                  {write_concurrency,true}]),

    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.   
    
  3. Update_1   来自@Derek Brown,包装的表格不能保证insert/1update/1被隔离。

    问题3:是否可以将其隔离? (除了Gen_server)

1 个答案:

答案 0 :(得分:1)

1)否。使用ets:new/2时从named_table返回的名称与您用于第一个参数的名称相同。这就是你在store表中存储的名称。因此,在insert/1update/1中,您也可以直接使用store_datastore_info原子。

2)不,插入和更新既不是原子也不是隔离。不是原子的,因为这不是函数在Erlang中的工作方式。例如,如果ets:insert/2中的第一次insert/1调用成功,但第二次因某种原因失败,则第一次调用没有任何类型的自动回滚。而不是孤立的,因为不能保证给定的函数(例如insert/1update/1)将以原子方式执行。其他过程可以在函数完成之前看到中间效果。

相关问题