【问题标题】:Erlang ETS atomic and isolatedErlang ETS 原子和隔离
【发布时间】:2017-03-01 07:59:53
【问题描述】:

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

对于下面的代码,我将两个表打包成一个

我的问题:

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

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

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

    init() -> ets:新(商店,[公共, 命名表, {read_concurrency, true}, {write_concurrency, true}]),

    数据 = ets:new(store_data, [public, 命名表, {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.   
    

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

Q3 : 是否可以将其隔离? (除了 Gen_server)

【问题讨论】:

    标签: erlang ets


    【解决方案1】:

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

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

    【讨论】:

    • 除了gen_server,有没有办法保证update被隔离?
    猜你喜欢
    • 2011-07-28
    • 2021-01-19
    • 2012-06-09
    • 2016-10-27
    • 2016-06-03
    • 2012-10-14
    • 1970-01-01
    • 2018-09-25
    • 2012-08-07
    相关资源
    最近更新 更多