Dela via


Optimistisk konkurrens

Optimistisk samtidighet härleder sitt namn från det optimistiska antagandet att kollisioner mellan transaktioner sällan kommer att inträffa; en kollision ska ha inträffat när en annan transaktion uppdaterar eller tar bort en rad med data mellan den tidpunkt då den läss av den aktuella transaktionen och den tid den uppdateras eller tas bort. Det är motsatsen till pessimistisk samtidighet, eller låsning, där programutvecklaren anser att sådana kollisioner är vanliga.

Vid optimistisk samtidighet lämnas en rad olåst tills det är dags att uppdatera eller ta bort den. Då läss raden om och kontrolleras för att se om den har ändrats sedan den senast lästes. Om raden har ändrats misslyckas uppdateringen eller borttagningen och måste försökas igen.

För att avgöra om en rad har ändrats kontrolleras dess nya version mot en cachelagrad version av raden. Den här kontrollen kan baseras på radversionen, till exempel tidsstämpelkolumnen i SQL Server eller värdena för varje kolumn på raden. Många DBMS stöder inte radversioner.

Optimistisk samtidighet kan implementeras av datakällan eller programmet. I båda fallen bör programmet använda en låg transaktionsisoleringsnivå, till exempel Read Committed; användning av en högre nivå upphäver den ökade samtidigheten som erhålls genom att använda optimistisk samtidighet.

Om optimistisk samtidighetskontroll implementeras av datakällan, anger programmet instruktionsattributet SQL_ATTR_CONCURRENCY till SQL_CONCUR_ROWVER eller SQL_CONCUR_VALUES. Om du vill uppdatera eller ta bort en rad kör den ett positionerat uppdaterings- eller borttagningsuttryck eller anropar SQLSetPos precis som med pessimistisk samtidighet. Drivrutinen eller datakällan returnerar SQLSTATE 01001 (marköråtgärdskonflikt) om uppdateringen eller borttagningen misslyckas på grund av en konflikt.

Om själva programmet implementerar optimistisk samtidighet, ställer det in attributet SQL_ATTR_CONCURRENCY till SQL_CONCUR_READ_ONLY för att läsa en rad. Om den jämför radversioner och inte känner till radversionskolumnen anropar den SQLSpecialColumns med alternativet SQL_ROWVER för att fastställa namnet på den här kolumnen.

Programmet uppdaterar eller tar bort raden genom att öka samtidigheten till SQL_CONCUR_LOCK (för att få skrivåtkomst till raden) och köra en UPDATE- eller DELETE-instruktion med en WHERE-sats som anger den version eller de värden som raden hade när programmet läste den. Om raden har ändrats sedan dess misslyckas satsen. Om WHERE-satsen inte unikt identifierar raden kan instruktionen även uppdatera eller ta bort andra rader. radversioner identifierar alltid rader unikt, men radvärden identifierar endast rader unikt om de innehåller primärnyckeln.