Nous utilisons NHibernate pour mettre à jour une table de comptes avec un solde pour un utilisateur. Un test qui nous contrecarre est la suivante:La colonne version du serveur SQL met à jour plus que ce qu'elle devrait
var s = NHibernateHelper.OpenSession();
var q = s.CreateQuery("Update Account set Balance=? where UserId=? and Version=?");
var acc = s.Load(1);
ITransaction tx = null;
for (int j = 0; j < NUM_UPDATES; j++)
{
int rowcount = 0;
var tx = s.BeginTransaction();
do
{
s.Refresh(acc);
q.SetDouble(0, acc.Balance + _amount).SetInt32(1, 1).SetBinary(2, acc.Version);
rowcount = q.ExecuteUpdate();
} while (rowcount <= 0);
tx.Commit();
}
ce code est en cours d'exécution à la fois dans un seul fil et dans plusieurs threads simultanément (d'où le versioning). il s'exécute correctement, mais - le numéro de version est incrémenté d'un nombre supérieur au nombre réel de mises à jour (NUM_UPDATES) d'une certaine valeur.
par exemple. si nous effectuons 16 mises à jour, le numéro de version est incrémenté de 16 ou 17. Si nous effectuons 1000 mises à jour, le numéro de version est incrémenté de 1004.
Si 16 threads exécutent ce même code (sur une machine à 4 coeurs) avec 1000 mises à jour chacune, puis nous obtenons beaucoup de tentatives évidemment, et la version est incrémentée de 16064 (1004 * 16).
Une idée de ce qui cause cela? Y a-t-il une cause d'alarme?
peut-être une question stupide - où le numéro de version est incrémenté? –
Ne pas jeter d'objets jetables, utiliser une session pour plusieurs transactions et utiliser une instruction de mise à jour manuscrite pour quelque chose que nhibernate doit gérer manuellement sont des causes d'alarme. – Paco
@Paco, c'est un cas de test très simplifié que nous avons concocté juste pour tracer ce problème. nous mettons toujours nos produits jetables à disposition, etc. merci pour nitpicking, bien que ... :) – Shachar