Couchdb är transaktionsbaserat som standard. Varje dokument i couchdb innehåller en _rev
nyckel. Alla uppdateringar av ett dokument utförs mot denna _rev
nyckel:-
- Hämta dokumentet.
- Skicka den för uppdatering med egenskapen _rev.
- Om uppdateringen lyckas har du uppdaterat den senaste _rev av dokumentet
- Om uppdateringen misslyckas var dokumentet inte nyligen. Upprepa steg 1-3.
Kolla in det här svaret av MrKurt för en mer detaljerad förklaring.
couchdb-recepten har ett bankexempel som visar hur transaktioner görs i couchdb.
Och det finns också denna atomic banköverföringar artikel som illustrerar transaktioner i couchdb.
Hur som helst är det gemensamma temat i alla dessa länkar att om du följer couchdb-mönstret att uppdatera mot en _rev
du kan inte ha ett inkonsekvent tillstånd i din databas.
Alla couchdb-dokument är unika eftersom _id
fält i två dokument kan inte vara samma. Kolla in visa kokboken
Redigera baserat på kommentar
Du kan använda separata dokument i det här fallet. Du infogar ett dokument, väntar på framgångssvaret. Lägg sedan till ett annat dokument som
{_id:'some_id','count':1}
Med detta kan du skapa en kartreduceringsvy som helt enkelt räknar resultaten av dessa dokument och du har en uppdateringsräknare. Allt du gör är att istället för att uppdatera ett enda dokument för uppdateringar infogar du ett nytt dokument för att återspegla en lyckad infogning.
Okej, jag har redan beskrivit hur du kan göra uppdateringar över separata dokument, men även när du uppdaterar ett enda dokument kan du undvika inkonsekvens om du:
- Infoga en ny fil
- När couchdb ger ett framgångsmeddelande -> försök att uppdatera räknaren.
Varför fungerar detta?
Detta fungerar för att när du försöker uppdatera update document
du måste ange en _rev
sträng. Du kan tänka på _rev
som en lokal stat för ditt dokument. Tänk på det här scenariot:-
- Du läser dokumentet som ska uppdateras.
- Du ändrar några fält.
- En annan begäran har redan ändrat originaldokumentet. Det betyder att dokumentet nu har en ny
_rev
- Men du ber couchdb att uppdatera dokumentet med en
_rev
det ärstale
som du läste i steg #1. - Couchdb genererar ett undantag.
- Du läser dokumentet igen och få den senaste
_rev
och försök att uppdatera den.
Så om du gör detta måste du alltid uppdatera mot den senaste versionen av dokumentet. Jag hoppas att detta gör saken lite tydligare.
Obs!
Som påpekat av Daniel, _rev
reglerna gäller inte för massuppdateringar.