Erlang: Mnesia: Поиск и обновление на основе полей кроме ключа

Если Вы хотите придерживаться FTP командной строки, необходимо попробовать NcFTP. Тогда можно использовать, заставляют-R рекурсивно получать папку. Вы также получите завершение.

6
задан Community 23 May 2017 в 10:27
поделиться

3 ответа

Тебе не о чем беспокоиться. Из документации mnesia:

Блокировки чтения могут быть общими, что означает, что если одной транзакции удается установить блокировку чтения для элемента, другие транзакции также могут получить блокировку чтения для того же элемента. Однако, если у кого-то есть блокировка чтения, никто не может получить блокировку записи для того же элемента. Если у кого-то есть блокировка записи, никто не может получить блокировку чтения или блокировку записи для одного и того же элемента.

Если транзакция имеет блокировку чтения для объекта, этот объект не может быть отредактирован другой транзакцией.

] Допустим, у вас есть две транзакции, T1 и T2, которые выполняются параллельно:

  1. T1 выполняет mnesia: match_object и устанавливает блокировку чтения для всех возвращенных объектов.
  2. T2 выполняет эквивалентную операцию. mnesia: match_object , и получает блокировку чтения для тех же объектов.
  3. T2 пытается получить блокировку записи для объектов (для редактирования).
  4. Mnesia автоматически прерывает T2, чтобы повторить попытку позже.
  5. T1 устанавливает блокировку записи для объектов и редактирует их.
  6. 1274] T1 завершается.
  7. Mnesia повторяет попытку T2.

Обратите внимание, что T2 может быть повторен несколько раз, в зависимости от того, сколько времени требуется T1 для завершения (т. Е. Снятия блокировок).

Согласно моим тестам, блокировка поведение mnesia: match_object несовместимо. Например, mnesia: match_object (mytable, {mytable, 2, '_'}, LockType) заблокирует только запись с помощью ключа 2, но mnesia: match_object (mytable, {mytable, ' _ ', test}, LockType) блокирует всю таблицу.

Также обратите внимание, что документация неверна, mnesia: match_object (Table, Pattern, write) действительно работает, и, кажется, следует той же схеме, что и «читать», т.е. если вы укажете ключ, только соответствующая запись будет заблокирована от записи; если вы не укажете ключ, вся таблица будет заблокирована для записи.

Вы можете проверить это самостоятельно, выполнив что-то вроде этого:

test() ->
    mnesia:transaction(fun()-> 
        Table = mytable,
        Matches = mnesia:match_object(Table, {Table, 2, '_'}, write),
        io:format("matched: ~p~n", [Matches]),
        spawn(fun()->mnesia:transaction(fun()->
                        io:format("trying to read~n",[]),
                        io:format("read: ~p~n", [mnesia:read(Table, 2, read)])
                        end) end),        
        timer:sleep(1000),
        RereadMatches = lists:map(fun(#mytable{id=Id}) -> mnesia:read(Table, Id, write) end, Matches),
        io:format("reread matches: ~p~n", [RereadMatches])
        end).

Путем изменения шаблона и типа блокировки, переданных в match_object ], а также номер ключа и тип блокировки, переданные в mnesia: read в порожденном процессе (или с помощью mnesia: write ), вы можете протестировать различные варианты поведения блокировки.

Приложение: См. Это сообщение Ульфа Вигера по той же теме.

Приложение 2: См. Раздел «Изоляция» в руководстве пользователя Mnesia.

Редактировать: Все вышеперечисленное было сделано на таблице типа набора,

1
ответ дан 17 December 2019 в 04:47
поделиться

Даже если он возвращает их под блокировкой чтения , вы все равно можете обновить их с помощью записи впоследствии. Все операции чтения / записи были просто оптимизацией.

Вы можете использовать таблицу order_set для реализации этого трюка мнезии для составных ключей .

2
ответ дан 17 December 2019 в 04:47
поделиться

Вы не можете просто заблокировать таблицу в транзакции заранее с помощью mnesia: write_lock_table (Tab ) ?

0
ответ дан 17 December 2019 в 04:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: