Dans une de mes pages ASP.NET, la validation d'un formulaire provoque l'insertion d'une "DemandeWeb" dans la base de donnée de l'application.
Afin d'insérer un enregistrement dans une base, je dois effectuer les opérations suivantes :
- Déterminer l'ID de l'enregistrement
- Insérer l'objet en entier
Je détermine l'ID du nouvel enregistrement en appellant un select max(id) from tableDesDemandes, et qui retourne au final max(id)+1
Puis j'insert mon objet métier auquel j'ai spécifié l'ID qu'il devait prendre.
-------
Mon problème concerne les accès concurrents : En effet si entre les étapes 1 et 2, un autre thread vient effectuer la première étape à son tour, il récupèrera le même ID que le thread précédent... causant au final forcémment une erreur au niveau de la base de donnée (la colonne ID est quand même clef primaire de la table)
Je souhaite donc utiliser les mutex pour résoudre mon probleme.
Ce qui donne :
private static Mutex mutex = new Mutex();
internal static Demande Create(Demande demande)
{
mutex.WaitOne();
demande.Id = GetNextId(); //renvoie max(id)+1
StringBuilder sb = new StringBuilder();
sb.Append(" insert into ...");
// autre code du append
DbCommand cmd = db.GetSqlStringCommand(sb.ToString());
db.AddInParameter(cmd, "DEMANDEID", DbType.Int32, demande.Id);
int nb = db.ExecuteNonQuery(cmd);
//On libère le mutex
mutex.ReleaseMutex();
return client;
}
Est ce la bonne solution pour éviter mon problème ? quid des performances ? Avez vous déjà été confronté à ce genre de problèmes ?
Je ne souhaite pas activer de méthodes spécifiques à la base de donnée retenue (en l'occurence, je travaille sur du mysql sur ce projet, donc je ne veux PAS d'auto increment dans une de mes colonnes !). Je souhaite faire quelque chose de standard !
Merci de votre retour
Partager