2016-10-19 2 views
1

ets doc, 단일 개체에 대한 모든 업데이트는 원 자성과 격리 된 상태로 보장됩니다. 즉, 하나의 객체에 대한 업데이트 작업이 영향을 미치지 않고 (원자력) 완전히 성공하거나 완전히 실패하거나 다른 프로세스 (격리)에서 중간 결과를 볼 수 없음을 의미합니다.얼랑 ETS 원자 적 분리 및 격리

  1. 이 얼랑의 일반적인 패턴입니다 : 다음 코드

    , 나는 한

    내 질문에 두 테이블을 포장?

  2. 삽입 및 업데이트의 경우 원자 단위로 분리되어 있습니까?

    -module (example_store). -export ([init/0, 삽입/1, 업데이트/1]).

    초기화() -> ETS : 새로운 (가기 [공립 named_table, {read_concurrency 사실} {write_concurrency 사실}])

    데이터 = ETS는 : 새로운 (store_data, [공공, named_table, {read_concurrency 사실 {}} write_concurrency 사실은),

    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. 
    

Update1 @Derek Brown의 포장 된 테이블에서는 insert/1update/1을 분리 할 수 ​​없습니다.

Q3 : 분리 할 수 ​​있습니까? (Gen_server는 따로)

답변

1

1) 아니요. named_table을 사용할 때 ets:new/2에서 반환하는 값은 첫 번째 인수에 사용한 것과 같은 이름입니다. 이것이 바로 store 테이블에 저장되는 이름입니다. 그러므로 insert/1update/1에서 store_datastore_info을 직접 사용할 수 있습니다.

2) 아니요, 삽입 및 업데이트는 원자 적이거나 분리되지 않습니다. Erlang에서는 함수가 작동하지 않기 때문에 원자 적이지 않습니다. 예를 들어 insert/1에있는 첫 번째 ets:insert/2 통화가 성공했지만 두 번째 이유가 실패한 경우 첫 번째 통화에 대한 자동 롤백이 없습니다. 그리고 주어진 기능 (예 : insert/1 또는 update/1)이 원자 적으로 실행된다는 보장이 없으므로 격리되지 않습니다. 다른 프로세스는 함수가 완료되기 전에 중간 효과를 볼 수 있습니다.

+0

gen_server와 별도로 'update'가 분리되어 있음을 보장하는 방법이 있습니까? – user3644708

관련 문제