Ez neked külön update-ben van? update version=?version+1 where version=?version and id=?id vagy csak lehagytad a többi mezőt? Ha ugyanabban az update-ben van, akkor csak az egyik alkalmazás szerver fog tudni update-elni.
Nekem amúgy az a gyanús, hogy olyan helyen és módon van használva az optimistic lock, ahol annak semmi értelmes szerepe nincs és így nyilván nem működik.
--
Tipikus (mondhatni tankönyvi) optimistic lock use-case az, hogy van egy balance(id, value, version) táblám. Meg kell nézzem, hogy van-e 100 pénze az illetőnek, ha van, le kell vonnom 100 pénzt az egyenlegből és vissza kell írnom, mindezt tranzakció nélkül.
Ilyenkor az történik, hogy van egy (123456789, 120, 0) értékem, lefut egy `SELECT * FROM balance WHERE id=123456789;`, ebből megkapom, hogy van 120 pénz és 0 a version, tehát beírhatom, hogy az új egyenleg 20 pénz. Lefuttatok egy `UPDATE balance SET value=20, version=1 WHERE id=123456789 AND version=0;` utasítást, ami csak akkor fog lefutni, ha a version értéke 0. Ha közben egy másik szálon, másik szerveren, másik programból ugyanerre a sorra valaki más levont pénzt (mondjuk 50 pénzt), akkor ez az UPDATE nem fog változtatást okozni, mert a version értéke már 1. A programom észre kell vegye, hogy nem futott le üzemszerűen az UPDATE, szóval újra kell futnia, ekkor már azt kapja, hogy (123456789, 70, 1) az értéke a sornak és nincs már 100 pénz az egyenlegen. Az adatbázisból tipikusan nem jön vissza exception, a futó programnak kell tudnia, hogy mikor kell megismételni a futást.