Ik ben bezig met een service oriented project waar een database bij komt kijken. Uiteindelijk wordt het systeem door vele gebruikers tegelijkertijd gebruikt waardoor ik nu tegen wat synchronisatie vraagstukken aan loop.
Normaal gesproken wordt data alleen exclusief gelockt in een restricte transactie bij een Update of Insert; bij Select krijgt de data een shared lock. Goed, en nu het probleem.
We nemen een veel voorkomend probleem: data toevoegen als deze niet bestaat, of updaten als deze wel bestaat. De eerste stap is dan doorgaans om de data te selecteren, en op basis daarvan te bepalen wat daarna gebeurt (toevoegen als geen data gevonden, updaten bij wel gevonden).
Stel dat het veel tijd kost voordat een transactie gecommit kan worden als er data gemaakt moet worden omdat deze niet gevonden is. Nu is dit een race condition: twee threads kunnen een Select doen, en daarna allebei een Insert proberen. Dit is uiteraard niet de bedoeling.
Wat is het remedie hiertegen? Een Serializable transactie zet nog steeds shared locks op geselecteerde data. Gewoon keihard updaten en kijken wat de affected rows zijn werkt, maar bij 0 affected rows moet je alsnog inserten en heb je dezelfde race condition.
Wat een oplossing is, is het gebruik van hints. Dit is mij echter te database specifiek (Linq ondersteunt dit ook niet). Vandaar de vraag hoe jullie hier tegenaan kijken. Is er bijvoorbeeld een mogelijkheid om een stored procedure zegmaar atomic te laten uitvoeren?
Ik werk in Visual Studio 2008 met SQL Server 2005 Standard, maar het moet zo algemeen mogelijk blijven.
Normaal gesproken wordt data alleen exclusief gelockt in een restricte transactie bij een Update of Insert; bij Select krijgt de data een shared lock. Goed, en nu het probleem.
We nemen een veel voorkomend probleem: data toevoegen als deze niet bestaat, of updaten als deze wel bestaat. De eerste stap is dan doorgaans om de data te selecteren, en op basis daarvan te bepalen wat daarna gebeurt (toevoegen als geen data gevonden, updaten bij wel gevonden).
Stel dat het veel tijd kost voordat een transactie gecommit kan worden als er data gemaakt moet worden omdat deze niet gevonden is. Nu is dit een race condition: twee threads kunnen een Select doen, en daarna allebei een Insert proberen. Dit is uiteraard niet de bedoeling.
Wat is het remedie hiertegen? Een Serializable transactie zet nog steeds shared locks op geselecteerde data. Gewoon keihard updaten en kijken wat de affected rows zijn werkt, maar bij 0 affected rows moet je alsnog inserten en heb je dezelfde race condition.
Wat een oplossing is, is het gebruik van hints. Dit is mij echter te database specifiek (Linq ondersteunt dit ook niet). Vandaar de vraag hoe jullie hier tegenaan kijken. Is er bijvoorbeeld een mogelijkheid om een stored procedure zegmaar atomic te laten uitvoeren?
Ik werk in Visual Studio 2008 met SQL Server 2005 Standard, maar het moet zo algemeen mogelijk blijven.