Couchdb er transaktionel som standard. Hvert dokument i couchdb indeholder en _rev
nøgle. Alle opdateringer til et dokument udføres mod denne _rev
nøgle:-
- Hent dokumentet.
- Send den til opdatering ved hjælp af egenskaben _rev.
- Hvis opdateringen lykkes, har du opdateret den seneste _rev af dokumentet
- Hvis opdateringen mislykkes, var dokumentet ikke for nylig. Gentag trin 1-3.
Se dette svar fra MrKurt for en mere detaljeret forklaring.
couchdb-opskrifterne har et bankeksempel, der viser, hvordan transaktioner udføres i couchdb.
Og der er også denne atomic bankoverførsler artikel, der illustrerer transaktioner i couchdb.
Alligevel er det fælles tema i alle disse links, at hvis du følger couchdb-mønsteret for opdatering mod en _rev
du kan ikke have en inkonsistent tilstand i din database.
Alle couchdb-dokumenter er unikke siden _id
felter i to dokumenter kan ikke være ens. Tjek se kogebogen
Rediger baseret på kommentar
Du kan bruge separate dokumenter i dette tilfælde. Du indsætter et dokument, venter på successvaret. Tilføj derefter et andet dokument som
{_id:'some_id','count':1}
Med dette kan du oprette en kortreducerende visning, der blot tæller resultaterne af disse dokumenter, og du har en opdateringstæller. Alt du gør er i stedet for at opdatere et enkelt dokument for opdateringer, indsætter du et nyt dokument for at afspejle en vellykket indsættelse.
Okay, så jeg har allerede beskrevet, hvordan du kan lave opdateringer over separate dokumenter, men selv når du opdaterer et enkelt dokument, kan du undgå inkonsekvens, hvis du:
- Indsæt en ny fil
- Når couchdb giver en succesmeddelelse -> forsøg at opdatere tælleren.
Hvorfor virker dette?
Dette virker, fordi når du forsøger at opdatere update document
du skal angive en _rev
snor. Du kan tænke på _rev
som en lokal stat for dit dokument. Overvej dette scenarie:-
- Du læser det dokument, der skal opdateres.
- Du ændrer nogle felter.
- I mellemtiden har en anden anmodning allerede ændret det originale dokument. Det betyder, at dokumentet nu har en ny
_rev
- Men du anmoder couchdb om at opdatere dokumentet med en
_rev
det erstale
som du læste i trin #1. - Couchdb genererer en undtagelse.
- Du læser dokumentet igen og få den seneste
_rev
og forsøg at opdatere den.
Så hvis du gør dette, vil du altid skulle opdatere mod den seneste revision af dokumentet. Jeg håber, at dette gør tingene lidt klarere.
Bemærk:
Som påpeget af Daniel, _rev
Reglerne gælder ikke for masseopdateringer.