web-dev-qa-db-fra.com

Quand dois-je utiliser 'for update nowait' dans les curseurs?

Dans quel cas devons-nous utiliser for update nowait en curseurs.

14
user1

En utilisant for update nowait entraînera l'occupation des lignes et acquiert un verrou jusqu'à ce qu'une validation ou une restauration soit exécutée. Toute autre session qui tente d'acquérir un verrou recevra un message d'erreur Oracle comme ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired au lieu d'attendre le déverrouillage.

Session1:

CURSOR abc_cur 
IS 
select * from dept where deptno =10 for update nowait;

Ici, les lignes sont verrouillées jusqu'à ce que le curseur soit fermé ou qu'un commit/rollback soit exécuté. Si, pendant ce temps, un autre utilisateur de la session 2 tente d'accéder aux mêmes enregistrements, cela générera une erreur comme indiqué ci-dessous:

Session2:

select * from dept where deptno =10 for update nowait;

Cet utilisateur ne peut même pas mettre à jour ou supprimer les mêmes enregistrements qui ont été verrouillés par la première session.

ERROR at line 1:
`ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired`

sage: Maintenant, si vous voulez manipuler certains ensembles d'enregistrements et que vous ne voulez pas qu'un autre utilisateur d'une autre session écrase vos données, vous devez d'abord verrouiller les enregistrements (en utilisant for update nowait) puis faites votre manipulation. Une fois votre manipulation terminée, fermez le curseur et validez.

EDIT Supposons qu'il y ait 10 lignes dans temp et j'exécute le script suivant dans ma session 1:

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

Dans la session 2, j'exécute ce qui suit pendant que le script de la session 1 est toujours en cours d'exécution

select * from temp;

10 rows found 

Si j'exécute le même script, dans la session 2, alors que le script dans la session 1 est toujours en cours d'exécution

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

Ensuite, je reçois ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release.

21
Gaurav Soni