Acces concurrent

Acces concurrent - SQL/NoSQL - Programmation

Marsh Posté le 05-04-2011 à 20:46:32    

:hello:  
 
Que se passe t'il lors d'un accès concurrent en écriture dans une DB type PostegreSQL
Par exemple, 2 appli en parallèle tente d'ajouter un user, actuellement la BDD possède un user jusqu'à 10. Les 2 applis récupèrent donc cette valeur, l'incrémente de 1 chacune , et veulent écrire l'user.id 11 chacune, alors qu'en fait, l'une aurait du prendre l'id 12.
 
Comment gérer cette problématique ?

Reply

Marsh Posté le 05-04-2011 à 20:46:32   

Reply

Marsh Posté le 05-04-2011 à 21:10:40    

le user.id est-il de type auto incremental ? ou le calcul tu au sein de ton application ?
 
je pencherais pour la second possibilite car postgre devrait savoir gerer ca tres bien.

Reply

Marsh Posté le 05-04-2011 à 21:12:36    

Si tu veux être sûr tu mets les 2 opérations dans une transaction. Par contre attention à ne pas en abuser parce que sinon ça va te créer des problèmes..


---------------
Si la vérité est découverte par quelqu'un d'autre,elle perd toujours un peu d'attrait
Reply

Marsh Posté le 05-04-2011 à 21:17:22    

Hum c'est vrai que l'auto increment peut aider..
Mais imaginons que c'est un traitement lambda (donc pas un auto increment), mais imaginons par exemple un compteur de visiteur.
Les 2 apps lisent 1100 visiteurs, chacune ajoute un et on se retrouve pourtant qu'avec 1101 visiteurs au lieu de 1102 ..
C'est ce genre de problème que j'aimerais éviter ..

Reply

Marsh Posté le 05-04-2011 à 21:18:06    

esox_ch a écrit :

Si tu veux être sûr tu mets les 2 opérations dans une transaction. Par contre attention à ne pas en abuser parce que sinon ça va te créer des problèmes..


Les 2 applis tournent en parallèle me ne peuvent pas communiquer entre elle donc pas moyen de faire une transaction non ?

Reply

Marsh Posté le 05-04-2011 à 21:22:10    

boblenain200 a écrit :

Hum c'est vrai que l'auto increment peut aider..
Mais imaginons que c'est un traitement lambda (donc pas un auto increment), mais imaginons par exemple un compteur de visiteur.
Les 2 apps lisent 1100 visiteurs, chacune ajoute un et on se retrouve pourtant qu'avec 1101 visiteurs au lieu de 1102 ..
C'est ce genre de problème que j'aimerais éviter ..


 
Dans ce cas la, tu es oblige de faire la synchronization au niveau de ton code. Pour la transaction, ca doit etre possible aussi, mais je ne sais pas comment faire ...

Reply

Marsh Posté le 05-04-2011 à 21:23:22    

boblenain200 a écrit :


Les 2 applis tournent en parallèle me ne peuvent pas communiquer entre elle donc pas moyen de faire une transaction non ?


Ah si les deux applis tournent en //, c'est different ...
 
La solution que je vois dans ce cas est de locker la table pendant le traitement ...
http://www.postgresql.org/docs/8.1 [...] -lock.html

Reply

Marsh Posté le 06-04-2011 à 16:48:10    

boblenain200 a écrit :


Les 2 applis tournent en parallèle me ne peuvent pas communiquer entre elle donc pas moyen de faire une transaction non ?


 
Les transactions se font au niveau du SGBD. L'appli ouvre une transaction, fait ce qu'elle a à faire, puis ferme la transaction. Donc pas de pb mais faut pas qu'une transaction dure trop longtemps, sinon ça va nuire aux perfs.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 06-04-2011 à 17:07:49    

rufo a écrit :


 
Les transactions se font au niveau du SGBD. L'appli ouvre une transaction, fait ce qu'elle a à faire, puis ferme la transaction. Donc pas de pb mais faut pas qu'une transaction dure trop longtemps, sinon ça va nuire aux perfs.


 
Si tu as un transaction du type :

Code :
  1. begin tran
  2. declare @id int
  3. SELECT @id = max(id) FROM users
  4. SELECT @id = @id + 1
  5. INSERT INTO users VALUES (@id, 'toto')
  6. commit tran


 
Avec ce type de transaction, est-on sur que que @id sera toujours different ? Mon intuition est que sans lock, on peut avoir deux fois la meme valeur ...


Message édité par mr simon le 06-04-2011 à 17:08:09
Reply

Marsh Posté le 06-04-2011 à 17:41:28    

Je pense que ça doit dépendre des sgbd. Dans le début de la transaction, y'a effectivement peut-être à préciser le type de transaction (de type lecture, écriture dans une table, dans un enregistrement donné...).


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 06-04-2011 à 17:41:28   

Reply

Marsh Posté le 07-04-2011 à 08:41:09    

En general pour eviter le probleme et les transactions on met l'ID dans une autre table (qui peut contenir plusieurs ID de differente tables).
 
Pour recuperer le prochain ID on fait juste un

Code :
  1. UPDATE IDTable
  2.     SET ID += 1
  3. Output inserted.id
  4. WHERE TableName = 'MyTable'


 
Sans avoir a utiliser de longue transaction on recupere l'ID qu'on viens d'incrementer.
 
C'est pour SQL Server, mais je suppose que c'est tout a fait fesable avec MySQL.
 
L'avantage de ce systeme est qu'on n'est pas obligé d'utiliser des chiffres pour l'ID, ca peut etre quasi n'importe quoi.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed