Ho una tabella in mnesia e devo aggiornare i singoli campi nei record in essa contenuti. Secondo Erlang : Mnesia : Updating a single field value in a row se faccio qualcosa di simile:Erlang: Mnesia: Ricerca e aggiornamento basato su campi diversi dalla chiave
update_a(Tab, Key, Value) ->
fun() ->
[P] = mnesia:wread({Tab, Key}),
mnesia:write(Tab, P#rec{a=Value}, write)
end.
Ora mi pare di capire, il codice precedente legge un record P
sulla base di un Key
, l'acquisizione di un blocco di scrittura sul disco, in modo che nessun altro le transazioni modificare questo record, mentre viene letto e scritto (o, in breve, aggiornato). Fin qui tutto bene.
Ora il mio requisito è che ho bisogno di poter leggere i record basati sia sullo Key
sia su un altro campo nella tabella e quindi eseguire un aggiornamento su di esso. Una funzione che farà questa ricerca è mnesia:match_object
. Il problema ora è che, la funzione supporta solo un blocco di lettura, non un blocco di scrittura, secondo lo http://www.erlang.org/doc/man/mnesia.html#match_object-3.
La conseguenza di ciò è che, suppongo nella funzione di cui sopra dovessi usare mnesia: match_object, otterrò un (gruppo di) record (s), tutti con blocchi di lettura. Dopo aver letto i record, ho bisogno di eseguire alcuni controlli sui dati recuperati e quindi scrivere nuovamente il record aggiornato solo se una condizione è soddisfatta. Ora, supponiamo che ci siano due transazioni parallele T1 e T2 avviate da due sorgenti diverse in esecuzione. Sia T1 che T2 accedono allo stesso record, allo stesso tempo. Dal momento che vengono letti bloccati, sia T1 che T2 saranno in grado di leggere i record in parallelo. Sia T1 che T2 eseguiranno lo stesso controllo sullo stesso record e, se la condizione corrisponde, entrambi procederanno ad eseguire l'aggiornamento. Ma, nel mio codice, se T1 e T2 dovessero essere eseguiti in serie, T1 avrebbe apportato modifiche al record e in T2, avrebbe letto questi record modificati e la condizione avrebbe avuto esito negativo e non sarebbe stato effettuato alcun aggiornamento.
In breve, ho bisogno di scrivere i record di blocco restituiti da mnesia: match_object. La documentazione afferma chiaramente che solo il blocco della lettura è supportato. Ci sono alternative?
UPDATE: ho avuto modo di sperimentare un po ', e una possibile soluzione ho pensato potrebbe essere quella di utilizzare chiavi composte. Supponiamo che io ho i dati scritti in una tabella come:
mnesia:transaction(fun() -> mnesia:write(mytable, #rec{i={1,2}, a=2, b=3}, write) end).
C'è un modo di ricercare voci, il lavoro non se ne frega?
ho provato questi, ma entrambi restituito risultati vuoti:
mnesia:transaction(fun()-> mnesia:read(mytable, {1,'_'}, read) end).
mnesia:transaction(fun()-> mnesia:read(mytable, {1,_}, read) end).
Per me ha molto senso, grazie! – ErJab