Vous devez vous assurer que autocommit
est défini sur false sur votre connexion. C'est la clé. Ensuite, vous procédez comme suit:
Faites votre sélection avec la clause mise à jour à la fin (sélectionnez colonne1, colonne2 de matable pour la mise à jour). Cela verrouillera la ligne.
Effectuez votre requête de mise à jour.
Emettez une validation explicite qui libérerait le verrou sur la ligne.
Bien sûr, rappelez-vous que le verrouillage de la ligne la verrouille de la modification. Une autre session pourrait encore interroger ces lignes. Par exemple, s'il s'agissait d'un ID et que le moyen de récupérer un nouvel ID était d'interroger la table en faisant select max(id) + 1 from table
. Verrouiller la ligne n'empêcherait pas une autre session de sélectionner cette option.
Mieux encore serait d'ignorer la sélection et mettre à jour les enregistrements en place et utiliser la clause returning
pour vous renvoyer les nouvelles valeurs mises à jour. Je ne l'ai jamais fait dans Ruby OCI8, donc je ne suis pas sûr si elle supporte cette fonctionnalité. Les documents pour cette clause dans une mise à jour sont ici:
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_10007.htm#i2126358
Oui, je l'utilise comme une carte d'identité. Je veux sélectionner la valeur actuelle du compteur (pour l'utiliser comme identifiant) et incrémenter le compteur. Cela empêche-t-il une autre session de faire un 'select for update' au lieu de simplement 'select'. Avec 'select for update', deux sessions peuvent toujours obtenir le même identifiant. Je vais essayer la clause 'return'. Merci. – user290870
@ ash34: Si une session a fait 'select for update' et qu'elle n'a pas encore été validée ou annulée, l'autre session effectuant un' select for update' bloquera l'attente pour pouvoir obtenir un verrou. Vous pouvez faire échouer rapidement l'autre session en utilisant 'select for update nowait'. Consultez une courte explication de nowait ici: http://docstore.mik.ua/orelly/oracle/prog2/ch06_11.htm –
Si vous voulez un compteur fiable, vous devez utiliser une séquence. – Martlark