来自ets doc,对单个对象的所有更新都保证是原子的和隔离的。这意味着对单个对象的更新操作要么成功要么完全失败而没有任何影响(原子性),并且其他进程(隔离)不能看到更新的中间结果。
对于以下代码,我将两个表包装成一个
我的问题:
这是Erlang中常见的模式吗?
对于插入和更新,它是原子的还是隔离的?
- 模(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.
Update_1
来自@Derek Brown,包装的表格不能保证insert/1
和update/1
被隔离。
答案 0 :(得分:1)
1)否。使用ets:new/2
时从named_table
返回的名称与您用于第一个参数的名称相同。这就是你在store
表中存储的名称。因此,在insert/1
和update/1
中,您也可以直接使用store_data
和store_info
原子。
2)不,插入和更新既不是原子也不是隔离。不是原子的,因为这不是函数在Erlang中的工作方式。例如,如果ets:insert/2
中的第一次insert/1
调用成功,但第二次因某种原因失败,则第一次调用没有任何类型的自动回滚。而不是孤立的,因为不能保证给定的函数(例如insert/1
或update/1
)将以原子方式执行。其他过程可以在函数完成之前看到中间效果。