Erlang ETS 原子和隔离
Posted
技术标签:
【中文标题】Erlang ETS 原子和隔离【英文标题】:Erlang ETS atomic and isolated 【发布时间】:2017-03-01 07:59:53 【问题描述】:来自ets doc,保证对单个对象的所有更新都是原子的和隔离的。这意味着对单个对象的更新操作要么成功,要么完全失败,没有任何影响(原子性),并且其他进程看不到更新的中间结果(隔离)。
对于下面的代码,我将两个表打包成一个
我的问题:
这是 Erlang 中的常见模式吗?
对于插入和更新,是原子的还是隔离的?
-模块(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/1
和update/1
被隔离。
Q3 : 是否可以将其隔离? (除了 Gen_server)
【问题讨论】:
【参考方案1】:1) 否。当您使用 named_table
时,从 ets:new/2
返回的名称与您用于第一个参数的名称相同。这就是您在store
表中存储的内容——名称。所以在insert/1
和update/1
中你也可以直接使用store_data
和store_info
原子。
2) 不,插入和更新既不是原子的,也不是孤立的。不是原子的,因为这不是函数在 Erlang 中的工作方式。例如,如果您的insert/1
中的第一个ets:insert/2
调用成功,但第二个由于某种原因失败,则第一个不会自动回滚。并且不是孤立的,因为不能保证给定的函数(例如,insert/1
或 update/1
)将以原子方式执行。在您的功能完成之前,其他进程可能会看到中间效果。
【讨论】:
除了gen_server,有没有办法保证update
被隔离?以上是关于Erlang ETS 原子和隔离的主要内容,如果未能解决你的问题,请参考以下文章