1

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

对于以下代码,我将两个表合二为一

我的问题:

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

  2. 对于插入和更新,它是原子的和孤立的吗?

    -模块(example_store)。-导出([初始化/0,插入/1,更新/1])。

    init() -> ets:new(store, [public, 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.   
    

来自@Derek Brown 的Update_1,被包裹的表不能保证insert/1update/1被隔离。

Q3:可以隔离吗?(除了 Gen_server)

4

1 回答 1

1

1) 否。ets:new/2使用时的返回named_table值与用于第一个参数的名称相同。这就是您在表中存储的内容store- 名称。所以 in insert/1andupdate/1你也可以直接使用store_dataandstore_info原子。

2)不,插入和更新既不是原子的,也不是孤立的。不是原子的,因为这不是函数在 Erlang 中的工作方式。例如,如果ets:insert/2您的第一次调用insert/1成功,但由于某种原因第二次失败,则第一次调用不会自动回滚。并且不是孤立的,因为不能保证给定函数(例如,insert/1or update/1)将被原子执行。在您的功能完成之前,其他流程可能会看到中间效果。

于 2016-10-19T17:41:13.943 回答