TL; DR;
99,9 % av webbutvecklarvärlden tror att korrekt användning av en RDBMS, tillsammans med transaktioner, förhindrar att deras applikationer ser dåliga data och introducerar allvarliga datafelfel. De har FEL.
Jag läste med stort intresse Kyle Kingsburys utmärkta artikel om Mongos konsistensmodell på https://aphyr.com/posts/322-call-me-maybe-mongodb-stale-reads
Up penet är denna kille super påslagen och vet vad han pratar om. Han gör jobbet och allt om den här artikeln är insiktsfull och välskriven.
Vad jag fann förvånansvärt var dock kommentarerna och vad de avslöjar om den genomsnittliga professionella utvecklaren:
Utvecklare tror att användningen av en RDBMS gör deras data säkra och de har absolut fel
Jag kan inte tala om hur många gånger jag har hamnat i bråk med "professionella" utvecklare och särskilt dumma sysadmins som verkligen tror att, genom att bara säga ordet RDBMS, snurra en kyckling runt huvudet tre gånger, och ansluta till den magiska enhörningen av databaser, kommer deras data att vara säkra och trygga som, du vet, … (något om) …. banktransaktioner och allt det där (nonsens) snack om transaktioner och fsync. Och en massa annat som ingen utvecklare jag någonsin träffat verkligen förstår eller har övervägt i sammanhanget med en HTTP-applikation (tips: statslös).
Innan jag fortsätter kommer jag att utmana:
- Skicka mig ditt github-användarnamn
- Låt mig välja en MySQL- eller PostgreSQL-baserad applikation som du skrivit (så att du inte kan förbereda den)
- Och jag kommer att hitta kodsökvägar som tillhandahåller både read-uncommitted och dirty-reads i din app inom 1 dag
- Om det inte finns några kommer jag att betala dig 1000 dollar
- Om det finns några får jag publicera vilken bild jag väljer av dig som ett tillägg till den här artikeln. Photoshop är tillåtet.
Hitta mig på /contact eller /team/ara-t-howard. Nu fortsätter vi…
Gåtan för dig utvecklare: vad är fel med den här kodsökvägen:
@db.transaction do
if no_user_exists_with_conditions?
@user = make_that_user_exists_with_those_conditions!
deliver_an_activation_email_to!(@user)
end
end
Låt mig avslöja något jordskakande för dig:
DENNA KODEN ÄR HELT FEL PÅ VARJE STÖRRE RDBMS, OCH VIRTUELLT VARJE
APPLIKATION, I VÄRLDEN
Jag försäkrar dig att e-postmeddelandet kommer att skickas två gånger.
Att förklara transaktioner är utanför omfånget för den här artikeln, men låt mig introducera dig till "phantom reads".
http://en.wikipedia.org/wiki/Isolation_%28database_systems%29#Phantom_reads
I koden ovan kan en andra, samtidig transaktion orsaka följande:
@db.transaction do
if no_user_exists_with_conditions?
# samtidigt har en andra transaktion skapat en dubblerad användare...
# det följande kommer att lyckas, i __båda__ transaktionerna
@user = make_that_user_exists_with_those_conditions!
# båda transaktionerna kommer att leverera e-postmeddelandet
deliver_an_activation_email_to!(@user)
end
end
# en av transaktionerna kommer att misslyckas med att begå, och gå *BOOM* men, till då,
# är det för sent: e-postmeddelandet har skickats två gånger och felet har gjorts
Jag vet, jag vet, du kan inte tro det. Men det är bara för att du aldrig brydde dig om att RTFD när det gäller vad "transaktion" betyder. Börja här:
http://www.postgresql.org/docs/9.1/static/transaction-iso.html
Obs den lilla tabellen. Låt mig översätta den åt dig:
-
Eftersom du inte har varje enskild sekvens av läsning&skrivning omsluten i en transaktion, och ibland bara slänger kod mot dina ORM-objekt direkt, lider du av den "skräckliga" verkligheten av "read-uncommitted" som nämns i artikeln
-
Eftersom du förlitar dig på standardisoleringsnivån lider du både av non-repeatable-reads och phantom reads. (Vet du ens vad standardisoleringsnivån är för din db och vad det betyder????)
-
Eftersom du inte ställt in din transaktionsnivå till "serializable" tror du felaktigt att din databas är snabb och säker. Du har felaktigt förlitat dig på databasen för att ge dataintegritet som en abstraktion som inte kräver kritiskt tänkande och applikationskod som är minst 10 gånger bättre än din. Du har alla skräckinspirationerna i Kyles artikel i dina RDBMS-baserade appar - och, inte bara vet du inte detta du är ganska säker på att din data är 'säker'
Och så frågar jag dig vilket är ett sämre ingenjörs beslut:
-
Välj ett standardbaserat verktyg som alla är mycket säkra på att de förstår och vet hur de använder säkert men, i dess vanliga användning, försäkrar