Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1539 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2  3
Auteur Sujet :

[Oracle] plsql : COMMIT dans une boucle FOR ?

n°1374174
orafrance
Posté le 24-05-2006 à 14:44:34  profilanswer
 

Reprise du message précédent :

Arjuna a écrit :

les lapins qui sortent du chapeau, moi je trouve ça moyen quand on bosse sur un ERP ou un TPE...


 
Essaye de donner un exemple pratique (et simple si possible :D) dans lequel ça géne STP.  
 
Moi j'en connais un seul, c'est dans le cas d'un trigger où tu peux être amené à désynchroniser du code, pour faire un SELECT sur la table qui déclenche le trigger notamment -> AUTONOMOUS_TRANSACTION et c'est réglé ;)

mood
Publicité
Posté le 24-05-2006 à 14:44:34  profilanswer
 

n°1374178
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 14:47:36  profilanswer
 

orafrance a écrit :

ce que tu décris ne repondrait pas au critère d'atomicité décrit ici il me semble : http://sqlpro.developpez.com/cours [...] ents/#L4.5


mais si :o
 
le transactions imbriquées, c'est justement pour faire du protonique :o
 
imagine.
j'ai un programme.
 
j'ouvre deux connections à mon sgbd. cnx1 et cnx2
on a un traîtement assychrone, je décrit "dans l'ordre des évèments" ce qu'il se passe dedans :
 
dans cnx1, j'ouvre une transaction tran1
dans tran1, j'update une table A
dans cnx2, j'interroge une table A <= j'ai les données à l'état initial
---- jusque là, tu me suis, c'est le fonctionnement simplissime d'oracle
dans tran1, j'update la table B
dans tran1, je crée une nouvelle transaction tran2
dans tran2, j'update table B <---- à partir des modifications effectuées par tran1
dans tran1, je lis table B <---- je suis locké par la transaction tran2
dans cnx2, je lis table B <---- j'ai mes données initiales
dans tran2, je commit <---- tran1 reprend la main, et trouve dans table B les données modifiées (le select de tout à l'heure)
dans tran1, je lis la table B <---- je vois toutes mes modifs
dans cnx1, je lis table B <---- j'ai toujours mes donnés intiales
dans cnx2, je lis table B <---- j'ai toujours mes donnés intiales
dans tran1, je commit
dans cnx1, je lis table B <---- j'ai enfin mes données modifiées par tout le bordel précédent
dans cnx2, je lis table B <---- j'ai enfin mes données modifiées par tout le bordel précédent
 
=> C'est ça le comportement normal. Et il est donc impératif de savoir à tout moment dans quelle transaction tu te trouves, puisque les mères doivent être lockées par les filles...

Message cité 1 fois
Message édité par Arjuna le 24-05-2006 à 14:53:58
n°1374179
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 14:48:50  profilanswer
 

orafrance a écrit :

après un commit toutes les transactions de la session courante sont validées et donc les transactions sont closes de facto


jamais de la vie :ouch:
 
seule la transaction active est commitée, les mère ne sont surtout pas impactée !!!

n°1374188
orafrance
Posté le 24-05-2006 à 14:54:22  profilanswer
 

Arjuna a écrit :

dans tran1, j'update la table B
dans tran1, je crée une nouvelle transaction tran2


 
Comment tu fais pour dire au SGBD d'interrompre son update pour créer une nouvelle transaction ???

n°1374189
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 14:54:22  profilanswer
 

PS: je viens de complexifier mon exemple de programme qui joue avec des transactions imbriquées

n°1374191
orafrance
Posté le 24-05-2006 à 14:55:25  profilanswer
 

orafrance a écrit :

Comment tu fais pour dire au SGBD d'interrompre son update pour créer une nouvelle transaction ???


 
J'ai réfléchit :D
 
Sous Oracle c'est possible via un trigger et alors on utilise les AUTONOMOUS_TRANSACTION... c'est donc parfaitement possible également

n°1374199
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 14:58:48  profilanswer
 

orafrance a écrit :

Comment tu fais pour dire au SGBD d'interrompre son update pour créer une nouvelle transaction ???


mais qu'est-ce que tu me parle d'interrompre l'update ?
 
je fais mon update.
je ne le commit pas.
et à l'interrieur de ma transaction courrante, je fais une nested transaction, qui est à L'INTERIEUR (et non A LA SUITE ou à la PLACE) de ma transaction.
la transaction tran1 continue à attendre patiemment d'être commitée.
par contre, la tran2, je vois les données modifiée par ma tran1, même si cette dernière n'a pas été commitée.
au commit de tran2, tran1 voit le modifications de tran2, mais ces modifications sont toujours invisible en dehors de tran1.
 
c'est à direque si tran1 est rollbackée, alors TOUT est rollbacké, puisque tran2 était inclue dans tran1


Message édité par Arjuna le 24-05-2006 à 15:00:38
n°1374203
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:00:05  profilanswer
 

ps: je sais pas pourquoi tu me parle de triggers depuis tout à l'heure, là on parle de blocs de PL/SQL bêtes et stupides :o

n°1374205
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:01:16  profilanswer
 

c'est con, j'ai désinstallé la doc de SQL Server. il y a un très bon cours sur les nested transaction dedans...

n°1374209
orafrance
Posté le 24-05-2006 à 15:01:43  profilanswer
 

Arjuna a écrit :

ps: je sais pas pourquoi tu me parle de triggers depuis tout à l'heure, là on parle de blocs de PL/SQL bêtes et stupides :o


 
la seule manière d'exécuter du code pendant une transaction c'est via un trigger... l'update de ta transaction déclenche donc un code qui dans ton exemple créera une 2° transaction... sinon, j'vois pas bien comment ton 1° update peut locker le 2°  :pt1cable:

mood
Publicité
Posté le 24-05-2006 à 15:01:43  profilanswer
 

n°1374212
orafrance
Posté le 24-05-2006 à 15:02:53  profilanswer
 

Plus clairement, sous Oracle ceci n'a pas de sens :
dans tran1, je lis table B <---- je suis locké par la transaction tran2  
 
En effet, un SELECT ne peut pas être bloqué par un lock ;)

n°1374213
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:03:01  profilanswer
 

voilà un petit truc sur les nested transaction.
ça m'a l'air pompeux, mais complet :)
http://publib.boulder.ibm.com/info [...] pw0056.htm

n°1374215
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:03:27  profilanswer
 

orafrance a écrit :

Plus clairement, sous Oracle ceci n'a pas de sens :
dans tran1, je lis table B <---- je suis locké par la transaction tran2  
 
En effet, un SELECT ne peut pas être bloqué par un lock ;)


ben carrément si !
et heureusement !!!
 
t'as un user TOTO qui fait une transaction.
il écrit dans A
il écrit dans B
mais il n'a toujours pas commité.
TITI arrive, et veut lire A afin d'ouvrir un curseur qui va boucler sur B pour le mettre à jour
=> vu que TITI tente de mettre à jour B, il est obligé d'attendre le ROLLBACK ou le COMMIT de TOTO.
=> et si TOTO COMMIT, mais que TITI se base sur les anciennes données de A pour modifier B, je te raconte pas l'intégrité des données !
 
 
Ben j'espère bien que tu vas être locké par la modif de TOTO, parceque sinon, tu pourrais avoir des surprises. en effet, les modifis de TITI seront totallement différentes selon si TOTO valide ou non sa transaction...

Message cité 2 fois
Message édité par Arjuna le 24-05-2006 à 15:07:04
n°1374221
orafrance
Posté le 24-05-2006 à 15:05:37  profilanswer
 

Arjuna a écrit :

ben carrément si !
et heureusement !!!


 
pourquoi heureusement ??? Tu vois les données qui seront commitées mais t'as pas à être locké... sinon, ce serait impossible de lire des tables mise à jour à longueur de journée  :heink:

n°1374228
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:07:22  profilanswer
 

modifié mon post en donnant un exemple

n°1374235
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:10:29  profilanswer
 

orafrance a écrit :

pourquoi heureusement ??? Tu vois les données qui seront commitées mais t'as pas à être locké... sinon, ce serait impossible de lire des tables mise à jour à longueur de journée  :heink:


c'est à toi quand tu écris une requête de mettre les hints nécessaites en fonction du niveau d'intégrité que tu dois garantir.
 
si c'est pour dire "on a 25678 clients", ouais, là tu t'en bas joyeusement les couilles qu'un insert soit en pending dans la table des clients.
 
si tu veux un extrait de compte à remettre à l'inspection des impôts, t'as tout intérêt à bien être locké par tout ce qui bouge dans la base, et bien locker aussi la table pendant ton select, afin de lire les données dans un étant complètement stable...
 
je t'imagine déjà en train de valoriser tes stocks pendant un mouvement inter-dépôt... "ah ben c'est bizarre, on a deux Queen Mary dans deux ports différents là dit-donc !"
 
et hop ! un Queen Mary qui sort du chapeau, un !

Message cité 1 fois
Message édité par Arjuna le 24-05-2006 à 15:12:12
n°1374252
orafrance
Posté le 24-05-2006 à 15:18:00  profilanswer
 

Arjuna a écrit :


t'as un user TOTO qui fait une transaction.
il écrit dans A
il écrit dans B
mais il n'a toujours pas commité.
TITI arrive, et veut lire A afin d'ouvrir un curseur qui va boucler sur B pour le mettre à jour
=> vu que TITI tente de mettre à jour B, il est obligé d'attendre le ROLLBACK ou le COMMIT de TOTO.
=> et si TOTO COMMIT, mais que TITI se base sur les anciennes données de A pour modifier B, je te raconte pas l'intégrité des données !


 
dans ce cas tu as une erreur de type "snapshot too old" parce que le curseur de TITI voit des block qui vont être flaggés comme modifiés en fin de transaction... c'est prévu évidemment ;)

n°1374258
orafrance
Posté le 24-05-2006 à 15:20:37  profilanswer
 

Arjuna a écrit :


si tu veux un extrait de compte à remettre à l'inspection des impôts, t'as tout intérêt à bien être locké par tout ce qui bouge dans la base, et bien locker aussi la table pendant ton select, afin de lire les données dans un étant complètement stable...


 
tu les lis dans un état stable, si les données ont changés pendant l'exécution du SELECT t'as une erreur... tu peux donc évidemment poser un lock sur la table mais dans ce cas tu interdis les utilisateurs de modifier les données. Mais c'est également possible, il n'y a aucun soucis  

n°1374262
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:23:05  profilanswer
 

orafrance a écrit :

dans ce cas tu as une erreur de type "snapshot too old" parce que le curseur de TITI voit des block qui vont être flaggés comme modifiés en fin de transaction... c'est prévu évidemment ;)


/me préfère être bloqué que planter en plein milieu sans savoir d'où ça vient, et perdre toute ma transaction pour rien...

n°1374270
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:25:03  profilanswer
 

orafrance a écrit :

tu les lis dans un état stable, si les données ont changés pendant l'exécution du SELECT t'as une erreur... tu peux donc évidemment poser un lock sur la table mais dans ce cas tu interdis les utilisateurs de modifier les données. Mais c'est également possible, il n'y a aucun soucis


Oracle, en fait, c'est les inventeurs des Crash Test Dummies :love:
 
"vous allez voir, vous pouver tout lancer en même temps etaprès y'a tout qui plante ! mais vous n'avez pas erdu de donnée hein ! et c'était super rapide !!! regarde maman ! sans les dents !"
 
perso: je préfère me bouffer un bon gros verroux dans la gueule, mais être sur d'arriver au bout de mon code :spamafote:

n°1374275
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:27:38  profilanswer
 

en fait, pour en revenir au queen mary qui change de port, ça fait un peu ça :
 
- tiens ? y'a deux queen mary ?
- mais nan, regarde, y'en a un qui coule
- ah ouais. tiens, pis maintenant l'autre il est plus dans son port
 
en fait, c'est ça, c'est pour tromper l'ennemi. pendant que ta transaction fait un écran bleu, tu la relances par derrière, et du coup tout le monde croit qu'il ne s'est rien passé, mais toi t'as viré 1M€ sur ton livret A :D
 
(tu auras noté que je suis en forme cet aprèm :D en forme de quoi, après, on n'en sait rien, mais j'y suis :D)

Message cité 1 fois
Message édité par Arjuna le 24-05-2006 à 15:29:24
n°1374277
orafrance
Posté le 24-05-2006 à 15:29:06  profilanswer
 

Arjuna a écrit :

/me préfère être bloqué que planter en plein milieu sans savoir d'où ça vient, et perdre toute ma transaction pour rien...


 
ce qui voudrait donc dire si on imagine une table de trace, que selon toi les SELECT sans clause WHERE dessus devrait être bloqué tant qu'il y a des mises à jour... c'est un dire un SELECT toujours bloqué. Moi je préfère choisir d'être bloqué quand c'est réellement nécessaire, en effet, un SGBD vie et les données bougent donc évidemment les vues de données sont vites obsolétes mais c'est normal.

n°1374286
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:32:23  profilanswer
 

ben nan.
 
je suis dans un select. je vais taper dans des données en cours de modification. si je suis flaggé comme acceptant de lire n'importe quoi même si c'est pas à jour, alors je lis, mais qu'on commit, rollback, ou remonte le titanic à la surface, je ne dois pas planter.
par contre, si je suis marqué comme nécessitant d'avoir des données "sûres", alors j'attends qu'il n'y ait plus de transactions en pending sur les tables à lire, et je peux demander à ce que personne ne puisse venir toucher à la table tant que je n'ai pas fini avec.
 
je ne vois pas ce qu'il y a à redire à ça :spamafote:
 
exemple sous sql server pour remplacer les séquences d'oracle, qui n'existent pas.
 
 
begin transaction
select curval from matablesequence where nom_sequence = 'ma sequence' with rowlock
update matablesequence  set curval = curval + 1 where nom_sequence = 'ma sequence' with rowlock
commit
 
=> le premier select lit la table, en demandant un lock exclusif sur les lignes lues (impossible de lire si la ligne est déjà lockée donc)
=> ce lock ne sera releasé que manuellement, ou si je commit/rollback
=> j'update la ligne lue avec la prochaine valeur de séquence
=> je commit pour releaser le lock et flusher mon update
 
j'espère bien qu'Oracle permet de faire la même chose quand même... sinon je comprends pas trop ce qu'on peut faire avec ce truc, et encore moins comment on peut avoir une once de confiance en lui :spamafote:

Message cité 1 fois
Message édité par Arjuna le 24-05-2006 à 15:37:30
n°1374287
orafrance
Posté le 24-05-2006 à 15:33:06  profilanswer
 

Arjuna a écrit :

en fait, pour en revenir au queen mary qui change de port, ça fait un peu ça :
 
- tiens ? y'a deux queen mary ?
- mais nan, regarde, y'en a un qui coule
- ah ouais. tiens, pis maintenant l'autre il est plus dans son port
 
en fait, c'est ça, c'est pour tromper l'ennemi. pendant que ta transaction fait un écran bleu, tu la relances par derrière, et du coup tout le monde croit qu'il ne s'est rien passé, mais toi t'as viré 1M€ sur ton livret A :D
 
(tu auras noté que je suis en forme cet aprèm :D en forme de quoi, après, on n'en sait rien, mais j'y suis :D)


 
J'ai pas dû être clair... Oracle ne fait pas de la génération spontanée de ligne hein  :D
 
Montre moi un exemple concret que j'essaye d'exécuter ça sous Oracle pour voir le problème STP ;)

n°1374289
orafrance
Posté le 24-05-2006 à 15:33:40  profilanswer
 

Arjuna a écrit :

ben nan.
 
je suis dans un select. je vais taper dans des données en cours de modification. si je suis flaggé comme acceptant de lire n'importe quoi même si c'est pas à jour, alors je lis, mais qu'on commit, rollback, ou remonte le titanic à la surface, je ne dois pas planter.
par contre, si je suis marqué comme nécessitant d'avoir des données "sûres", alors j'attends qu'il n'y ait plus de transactions en pending sur les tables à lire.
 
je ne vois pas ce qu'il y a à redire à ça :spamafote:


 
absolument rien et évidemment c'est ce qui est fait sous Oracle également ;)

n°1374298
orafrance
Posté le 24-05-2006 à 15:39:05  profilanswer
 

en tout cas, si ça peut te rassurer, j'ai jamais vu d'inconsistence de données sous Oracle alors je m'explique peut-être mal mais ce que tu décris est prévu ;)

n°1374319
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 15:46:41  profilanswer
 

orafrance a écrit :

J'ai pas dû être clair... Oracle ne fait pas de la génération spontanée de ligne hein  :D
 
Montre moi un exemple concret que j'essaye d'exécuter ça sous Oracle pour voir le problème STP ;)


 
une transaction :
 
update gens set ville = 'monaco' where nom = 'elizabeth' and ville= 'amsterdam';
update ports set port = 'monaco' where port = 'amsterdam' and bateau = 'queen mary';
 
maintenant, pendant ce temps la, j'ai un autre process qui arrive, qui lui, va faire du ménage dans la base.
 
select ville from gens;
for mes villes
  if not exists(select null from ports where port = mavillecourrante)
     delete guignol from gens where ville = port; --ben ouais, il a plus de bateau, alors on s'en balance du gars
  end;
loop;
 
ok, tu me suis ?
 
maintenant, le select qui boucle se fait avant le commit.
donc élisabeth est toujours à amsterdam avec son queen mary.
par contre, dans le for, on arrive sur monaco. y'a pas de bateau, puisqu'on a lu qu'elle et son queen mary étaient encore à amsterdam. donc paf, on va balourder élisabeth à l'eau parcequ'elle a soit-disant perdu son bateau, alors que c'est juste qu'on compare des artichauds et des petits poids (données commitées et non commitées)
et par contre, le queen mary arrive à monaco tout seul :spamafote:
 
d'où le besoin absolu de demander un lock exclusif sur l'ensemble des lignes lues par un select quand ce dernier est utilisé pour un curseur qui va modifier une autre table


Message édité par Arjuna le 24-05-2006 à 15:53:30
n°1374334
orafrance
Posté le 24-05-2006 à 15:58:39  profilanswer
 

je viens de tester et il n'y a aucun problème... on est locker sur le DELETE en attente du COMMIT qui va passer ville de amsterdam à monaco. Delete qui doit supprimer les gens d'amterdam puisqu'il n'y a pas de bateau. Quand le lock est levé, il n'y a plus de ligne à deleter puisqu'on est effectivement à monaco :
 
session1

Code :
  1. SQL> select * from gens;
  2. NOM                  VILLE
  3. -------------------- --------------------
  4. elizabeth            amsterdam
  5. guignol              monaco
  6. SQL> select * from ports;
  7. PORT                 BATEAU
  8. -------------------- --------------------
  9. monaco               queen mary
  10. SQL> update gens set ville = 'monaco' where nom = 'elizabeth' and ville= 'amsterdam';
  11. 1 ligne mise à jour.
  12. SQL> select * from gens;
  13. NOM                  VILLE
  14. -------------------- --------------------
  15. elizabeth            monaco
  16. guignol              monaco
  17. SQL> commit;
  18. Validation effectuée.


 
session2

Code :
  1. SQL> select * from gens;
  2. NOM                  VILLE
  3. -------------------- --------------------
  4. elizabeth            amsterdam
  5. guignol              monaco
  6. SQL> select * from ports; 
  7. PORT                 BATEAU
  8. -------------------- --------------------
  9. monaco               queen mary
  10. SQL> set serveroutput on                                     
  11. SQL> declare                                                 
  12.   2  exist number;                                             
  13.   3  begin                                                     
  14.   4  for i in (select ville from gens) loop                   
  15.   5  select count(1) into exist                               
  16.   6  from ports where port=i.ville;                           
  17.   7  dbms_output.put_line('ville -> '||i.ville ||' -> '||exist);
  18.   8  if exist = 0 then                                         
  19.   9  delete from gens where ville = i.ville;                   
  20. 10  end if;                                                   
  21. 11  end loop;                                                 
  22. 12  end;                                                     
  23. 13  /
  24. ville -> amsterdam -> 0
  25. ville -> monaco -> 1
  26. Procédure PL/SQL terminée avec succès.
  27. SQL> select * from ports;
  28. PORT                 BATEAU
  29. -------------------- --------------------
  30. monaco               queen mary
  31. SQL> select * from gens;
  32. NOM                  VILLE
  33. -------------------- --------------------
  34. elizabeth            monaco
  35. guignol              monaco



Message édité par orafrance le 24-05-2006 à 16:32:17
n°1374359
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 16:16:17  profilanswer
 

rien n'empêche que je sois déjà à monaco avec mon 521 :o
et du coup y'a déjà monaco dans la table.
 
ceci dit, dans ce cas, je rentre en queen mary :D


Message édité par Arjuna le 24-05-2006 à 16:16:55
n°1374405
Beegee
Posté le 24-05-2006 à 16:42:35  profilanswer
 

SELECT ... FOR UPDATE, non ? :)
 
edit : quoique je sais pas si ça marche avec le DELETE ... probablement.
Et dans ce cas, le SELECT est bloqué tant que le COMMIT n'est pas fini, enfin je pense :D


Message édité par Beegee le 24-05-2006 à 16:43:17
n°1374442
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 17:21:04  profilanswer
 

for update c'est goret si tu fais rien dedans ;)
 
nan, je pense qu'il y a des hints avec oracle comme sur SQL Server ou PostGre
 
Avec SQL Server, on rajoute "with" après le FROM, en indiquand le niveau de lock (on peut aussi forcer les index, etc.) comme les hints sous Oracle quoi ;)


Message édité par Arjuna le 24-05-2006 à 17:21:15
n°1374446
orafrance
Posté le 24-05-2006 à 17:27:22  profilanswer
 

non, il n'y a pas ça sous Oracle... seul les FK ou les indexes permettre de locker au niveau ligne :)

n°1374530
Arjuna
Aircraft Ident.: F-MBSD
Posté le 24-05-2006 à 18:55:57  profilanswer
 

y'a pas de hints de lock ???

n°1375342
orafrance
Posté le 26-05-2006 à 09:30:59  profilanswer
 

non

n°1375447
Arjuna
Aircraft Ident.: F-MBSD
Posté le 26-05-2006 à 12:20:47  profilanswer
 

et après, on va me dire que c'est pas pourri :o

n°1375635
orafrance
Posté le 26-05-2006 à 16:25:57  profilanswer
 

bah non, il n'y a pas besoin parce qu'il est suffisamment intelligent pour ne verrouiller que ce qui est nécessaire :)


Message édité par orafrance le 26-05-2006 à 16:26:03
n°1649471
leguru2007
Posté le 27-11-2007 à 11:32:56  profilanswer
 

Bonjour,
Je me suis inscrit juste pour vous éclairer...
D'abord il faut comprendre que chez ORACLE toute modification (update,insert etc..) se fait necessairement dans le cadre d'une transaction même si vous ne l'avez demandée explicitement: C'est la notion de transaction implicte; C'est à dire que dès lors où vous voulez apporter des modifications à votre base vous devez passer necessairement par une transaction. L'avantage est que vous pouvez faire un rollback et annuler les modifications si vous vous êtes trompés. Et c'est pour cela qu'il faut toujours faire un commit à la fin de l'opération. Et la base de données Oracle se comporte toujours comme ça. Et l'autocommit alors ? En fait votre système Oracle ne connait pas d'autocommit. La notion d'autocommit est lié au client (Sqlplus, TOAD, etc..) que vous utilisez pour interroger la base. Vous dites au client de faire le commit à votre place et c'est ce qu'il fait. La base de données ne fait qu'executer ce qu'on lui dit. Ce choix de fonctionnement est plus difficile à mettre en oeuvre que celui fait par bon nombre de SGBD mais l'avantage c'est la souplesse. Je parlerai des verrous plus tard et vous verrez la force de ORACLE. Oracle a fait des choix compliqués à mettre en oeuvre mais à la fin on a un système robuste et performant. Juste un peu compliqué parce que l'architecture est complexe.
Bonne journée à tous

n°1649504
leguru2007
Posté le 27-11-2007 à 11:54:49  profilanswer
 

Parlons des locks.
Chez Oracle on ne verrouille que si on ne peut pas faire autrement.
Si vous êtes en train de modifier une ligne dans un bloc, oracle ne verrouillera que la ligne pour empêcher toute modification. C'est à dire que la ligne reste acessible en lecture aux autres sessions et toutes les autres lignes de la table ou du bloc reste accessibles aussi bien en lecture qu'en modification. Pour permettre la lecture de la ligne en modification Oracle utilise le tablespace UNDO. Que font les autres ?  Sur SQL SERVER par exemple non seulement la ligne en question est vérrouillée mais toutes les autres lignes de la page (bloc) sont aussi vérouillées. vous ne pouvez même pas INTERROGER les autres lignes de la table. Les conséquences pour ce choix compliqué sont extraordinaires pour ORACLE. Une grande partie des technologie flashback est basée sur l'utilisation des données UNDO.
Merci et bonne journée à tous...

n°1649746
MagicBuzz
Posté le 27-11-2007 à 16:36:29  profilanswer
 

leguru2007 a écrit :

Parlons des locks.
[...]
Sur SQL SERVER par exemple non seulement la ligne en question est vérrouillée mais toutes les autres lignes de la page (bloc) sont aussi vérouillées.


C'est faux (comme nombre de reproches courrament faits à SQL Server (genre l'impossibilité d'utiliser plusieurs charset et méthodes de comparaison de chaînes dans une même table).
 
SQL Server sait parfaitement effectuer des locks jusqu'au niveau de la ligne, et c'est d'ailleurs ce qu'il fait par défaut.
Ensuite, tu peux jouer avec les hints de verroux pour modifier le comportement (un TABLOCKX, évidement, tu vas booster les perfs de ta transaction, mais c'est à toi de le spécifier).
http://msdn2.microsoft.com/fr-fr/library/ms187373.aspx
 
Preuve avec SQL Server 2005 Express (j'ai pas de 2000 sous la main, mais ça fonctionne aussi, il me semble d'ailleurs déjà avoir produit ici ce protocole de test sous cette version) :
 
Table "com" :

Code :
  1. CREATE TABLE com
  2. (
  3.     insee char(5) NOT NULL PRIMARY KEY,
  4.     codpos char(5) NOT NULL,
  5.     nomcom char(26) NOT NULL,
  6.     nomdep char(23) NOT NULL
  7. )


 
La lignes avec lesquelle je vais jouer :

Code :
  1. SELECT * FROM com WHERE insee IN ('21230', '21231')



insee codpos nomcom                     nomdep
----- ------ -------------------------- -----------------------
21230 21120  DIENAY                     COTE D'OR              
21231 21000  DIJON                      COTE D'OR              
 
(1 ligne(s) affectée(s))


 
Session 1 :

Code :
  1. begin tran
  2. UPDATE com SET nomcom = 'PLOP' WHERE insee = '21231'


 
Session 2 :

Code :
  1. begin tran
  2. UPDATE com SET nomdep = 'AUBE' WHERE insee = '21231'


LOCK effectivement (SQL Server ne gère pas les locks au niveau du champ).
 
Session 1 :

Code :
  1. rollback


 
Session 2 se débloque.
 
Session 2 :

Code :
  1. rollback


 
Session 1 :

Code :
  1. begin tran
  2.  
  3. UPDATE com
  4. SET nomcom = 'PLOP'
  5. WHERE insee = '21231'


 
Session 2 :

Code :
  1. begin tran
  2.  
  3. UPDATE com
  4. SET nomcom = 'PLOP'
  5. WHERE insee = '21230'


Aucun problème.
 
Session 1 :

Code :
  1. SELECT * FROM com WHERE nomcom = 'PLOP'


 
Locké
 
Session 2 :

Code :
  1. SELECT * FROM com WITH(READUNCOMMITTED) WHERE nomcom = 'PLOP'



insee codpos nomcom                     nomdep
----- ------ -------------------------- -----------------------
21230 21120  PLOP                       COTE D'OR              
21231 21000  PLOP                       COTE D'OR              
 
(2 ligne(s) affectée(s))


(Potentiellement dangereux, ce hint permet de ne pas tenir compte des locks actifs, et retourne les lignes lockées, y compris si elles ne sont pas commitée dans les autres sessions.
 
Session 2 :

Code :
  1. SELECT * FROM com WITH(READPAST) WHERE nomcom = 'PLOP'



insee codpos nomcom                     nomdep
----- ------ -------------------------- -----------------------
21230 21120  PLOP                       COTE D'OR              
 
(1 ligne(s) affectée(s))


Permet de consulter la table alors que des lignes sont en cours de lock (les lignes en cours de transaction sont zappées entièrement)
 
Session 2 :

Code :
  1. rollback


 
Session 1 débloquée avec pour résultat :


insee codpos nomcom                     nomdep
----- ------ -------------------------- -----------------------
21231 21000  PLOP                       COTE D'OR              
 
(1 ligne(s) affectée(s))


 
Session 2 :

Code :
  1. SELECT * FROM com WHERE insee = '21230'



insee codpos nomcom                     nomdep
----- ------ -------------------------- -----------------------
21230 21120  PLOP                       COTE D'OR              
 
(1 ligne(s) affectée(s))


Même si des lignes sont en cours de lock, à partir du moment où on ne tente pas d'y toucher, on peut les consuter sans problème, et sans avoir besoin de table hint.
 
Session 1 :

Code :
  1. rollback


 
Enfin voilà quoi... Faut pas dire des bêtises comme ça :o


Message édité par MagicBuzz le 27-11-2007 à 17:03:49
n°1661916
leguru2007
Posté le 21-12-2007 à 14:32:27  profilanswer
 

J'ai fait un test pareil avec mon formateur lors d'une session de formation SQL SERVER (VERSION 2005) pour professionnels ORACLE. LE RESULTAT ETAIT CLAIR. ET même tous les manuels et documentation sur SQL SERVER 2005 sont unanimes. SERVER 2005 VERROUILLE EXCLUSIVEMENT AU NIVEAU PAGE LORS D'UNE TRANSACTION (les pages sont appellées bloc chez ORACLE. Elles sont de 8k sur SQL SERVER contrairement à ORACLE où vous pouvez choisr la taille de votre block. NB Oracle utilise la notion de page avec l'utilitaire dbverify) Alors cher Monsieur "MagicBuzz" revoyez votre cours sur SQL SERVER 2005. Revoyez surtout les notions de niveau d'isolation, de verrous, de verrous exclusifs et partagés et vous comprendrez ce que je dis. Je parle bien de SQL SERVER VERSION 2005 et non d'une autre.
Je te conseille SQL SERVER 2005 LA BIBLE de Paul Nielsen parce que le manuel de formation MICROSOFT n'est pas trop bavard là dessus.
BONNE CHANCE

n°1661964
MagicBuzz
Posté le 21-12-2007 à 15:40:43  profilanswer
 

Et moi je te conseille de lire la documentation.
http://msdn2.microsoft.com/fr-fr/library/ms187373.aspx
 
Avant de dire des conneries, refais mon jeu de test...
Si tu utilises correctement les table hint, tu peux parfaitement faire ce que tu veux.
 
C'est pas parceque SQL Server fonctionne d'une certainement manière par défaut qu'il ne sait pas travailler autrement.
 
Au lieu de me parler de formateur superman qui vous a montré comment planter sql server 2005 en 2 temps 3 mouvements, reposte jeu de requêtes, et on en reparlera.
C'est pas parcequ'un formateur sais pas se servir du produit sur lequel il vous forme que le produit est mauvais. Si à chaque fois que j'ai fait des formations je devais croire ce que m'ont dit les formateurs, je certifierais comme morticus qu'Oracle ne supporte des sous-requête que dans la clause WHERE, qu'il ne supporte pas le full outer join et surtout qu'il est impossible d'avoir deux index uniques sur une même table (sisi, fait l'avoir entendu en formation pour le croire).
 
Alors ton formateur, il est bien gentil, mais désolé si je ne me fie pas une seconde à une simple déclaration d'un gars qui n'a absolument jamais travaillé de sa vie sur l'outils (ben ouais, quand on est formateur, on exploite pas l'outil, sinon tous les profs d'autoécole seraient des champions de formule 1 pas vrai ?).

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3

Aller à :
Ajouter une réponse
 

Sujets relatifs
[Oracle] Execute Immediate ne fait rien ... ?[résolu]Boucle travaillant avec toutes les valeurs issues d'un formulaire
Un goto ou bien une boucle ! Comment faireBoucle sur formulaire
[resoluTRIGGER REPLICATION] replication de table sur deux bases repar[JAVA] Pb de connexion DB Oracle à partir d'une applet [Résolu]
comment faire défiler des images en boucle sur un site ?Passer une variable php->js dans une boucle
[Résolu][Oracle Text] chargement de fichiers / indexRécupération de variables en boucle
Plus de sujets relatifs à : [Oracle] plsql : COMMIT dans une boucle FOR ?


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)