SlideShare ist ein Scribd-Unternehmen logo
1 von 76
@ Vincent Englebert - UNamur 1
Transactions & Concurrence
version 2.0
Transactions & Concurrence
version 2.0
1.1. TransactionTransaction
2.2. Gestion de la concurrenceGestion de la concurrence
3.3. Gestion de la concurrence entre transactionsGestion de la concurrence entre transactions
(sérialisation des transactions)(sérialisation des transactions)
4.4. Protocole Two Phase CommitProtocole Two Phase Commit
5.5. Transactions imbriquéesTransactions imbriquées
6.6. Modèle X/OPENModèle X/OPEN
7.7. Transactions & CORBATransactions & CORBA
8.8. Exemple: transfert bancaire & CORBAExemple: transfert bancaire & CORBA
Conditions
Ces matériaux pédagogiques devenus obsolètes dans notre cursus
sont distribués en l’état et ne sont plus maintenus.
Tout emprunt vers d’autres supports respectera les conditions de la
licence Creative Commons Attribution telle que déclarée dans l’entête
en référençant:
Source: Université de Namur Belgique – Faculté d’informatique – V.
Englebert
Si jamais, une information était incorrectement référencée dans ce
document, les ayants-droits sont priés de me contacter afin de corriger
le document: vincent.englebert (at) unamur.be
@ Vincent Englebert – Unamur 2
@ Vincent Englebert - UNamur 3
Transaction
Transaction
= Séquence d’instructions exécutées.
Idéalement, une transaction est une opération (au sens macro) qui
opère une transition valide dans l'espace des états autorisés du
système.
Les propriétés ACID
Atomic
Une transaction s’effectue complétement ou pas du tout
Consistent
Une transaction préserve l’intégrité de la base de données
Isolated
Une transaction ne doit pas se soucier de l’existence d’autres transactions.
Durable
L’effet d’une transaction doit être permanent.
i1
i2
i3 i4 i5
@ Vincent Englebert - UNamur 4
Atomic
Si une transaction effectue un versement d’un compte à un autre, elle
ne peut s’opérer à moitié
Dupont.compte=Dupont.compte-100$
Martin.compte=Martin.compte+100$
Si un système garantit la propriété AACID, et si un crash (soft/hard)
survient au milieu d’une transaction, le système nous garantit que l’état
de la base de données sera restaurée comme si la transaction n’avait
jamais été initiée.
begin abort commit
Transaction
@ Vincent Englebert - UNamur 5
Limites de l’atomicité
Begin-transaction
IF compte >10.000$
THEN BEGIN
print(« RETRAIT AUTORISÉ »);
compte:=compte - 2.000$
END
End-transaction
Le problème se pose avec toutes les opérations qui ne sont pas
« recoverable »
impression
hardware
distributeur, lecteur de cartes, tapis roulant, moteur, …
communication
comment annuler un envoi de mail ?
@ Vincent Englebert - UNamur 6
Consistency
Vérifier que les contraintes d’intégrité sont vérifiées et que la base de
données représente des états valides.
Primary key
Contraintes référentielles
User constraint
décédé ⇒ date_décés is not null
select total_des_commandes
from client
where ncli=$1
=
select sum(prixunitaire*quantité)
from detail, produit, commande
where detail.npro=produit.npro
and detail.com=commande.ncom
and commande.ncli=$1
@ Vincent Englebert - UNamur 7
Isolation
Soient T1=[a1
1
,…,a1
n
] et T2=[a2
1
,…,a2
m
] deux transactions composées d’actions.
Une exécution des actions de T1 et T2 est sérialisable si elle produit les mêmes
effets que l’exécution de T1 et T2 en série
c-à-d: il existe une combinaison (ici: T1;T2 ou T2; T1) dont l'exécution produit les
mêmes résultats et mêmes effets que l'ordonnancement proposé.
Exemple:
T(X) ≡ IF (X.compte > retrait )
THEN X.compte:=X.compte-retrait
une exécution des transactions T(dupont) et T(dupont) où l’on testerait en même
temps le montant du compte n’est pas sérialisable, puisque si on exécute ces
transactions les unes après les autres, la seconde pourrait échouer !
Compte=1000 & retrait=700
Le respect de cette propriété nous garantit que si le système (DB, scheduler,
…) exécute des transactions en parallèle, cela aura les mêmes
caractéristiques qu’en série.
Le programmeur n’a pas à tenir compte du contexte dans lequel va s’exécuter
la transaction. Les modifications opérées durant une transaction ne sont pas
visibles en dehors de cette dernière.
@ Vincent Englebert - UNamur 8
Le problème du lost-update
Trois comptes A,B,C avec 100, 200 et 300 dollars.
On exécute deux transactions matérialisant deux transferts:
transfert de 4$ de A vers B et transfert de 3$ de C vers B.
L'exécution en parallèle de ces deux transactions peut amener à des
inconsistences, si l'on ordonne mal les opérations qui les constituent.
Transaction 1 balance1 A B C balance2 Transaction 2
? 100$ 200$ 300$ ?
balance1:=A
100$
A:=balance1-4
96$
balance2:=C
300$
C:=balance2-3
297$
balance1:=B
200$
balance2:=B
200$
B:=balance2+3
203$
B:=balance1+4
204$
96$ 204$ 297$
lost-update
@ Vincent Englebert - UNamur 9
Problème de la lecture erronée
Une première transaction effectue un transfert d'argent entre deux
compte alors qu'une autre calcule la somme des comptes.
Transaction 1 balance1 A B C balance2 Transaction 2
? 100$ 200$ 300$ ?
balance1:=A
100$
A:=balance1-100
0$
balance2:=A;
balance2:=balance2+B
balance2:=balance2+C
500$
balance1:=B
200$
B:=balance1+100
300$
0$ 300$ 300$ 500$
@ Vincent Englebert - UNamur 10
Exécution sérialisée
Il est néanmoins possible de trouver un plan d'exécution parallèle (ou
interleaving) qui présente les mêmes caractéristiques qu'une exécution
en série des deux transactions.
Transaction 1 balance1 A B C balance2 Transaction 2
? 100$ 200$ 300$ ?
balance1:=A
A:=balance1-4
100$ 96$
balance2:=C
C:=balance2-3
297$ 300$
balance1:=B;
B:=balance1+4
200$ 204$
balance2:=B
B:=balance2+3
207$ 204$
96$ 207$ 297$
@ Vincent Englebert - UNamur 11
Durabilité
Si des opérations doivent mettre à jour des données persistantes, leur
mise à jour doit être effective.
Exemple:
le système doit être capable de prendre en compte tout problème qui
surviendrait lors de l’enregistrement d’une information.
@ Vincent Englebert - UNamur 12
Gestion de la concurrence
Le mécanisme le plus répandu pour garantir qu’une exécution de
transactions est sérialisable est la pose de verrous (lock).
Principes
chaque transaction réserve les ressources qu’elle utilise en posant un verrou
dessus
ligne de table SQL  fichier  disque  propriété;
On distingue des verrous en écriture et en lecture (il peut y en avoir plus)
Une transaction doit poser un verrou en lecture (resp. en écriture) sur une
ressource avant de la lire (resp. écrire).
La pose d’un verrou réussit ou échoue selon le tableau suivant:
Lecture Écriture
Lecture succès échec
Écriture échec échec
La pose d'un verrou avant d’accéder à une ressource ne garantitLa pose d'un verrou avant d’accéder à une ressource ne garantit
néanmoins pas la sérialisation des transactions !néanmoins pas la sérialisation des transactions !
@ Vincent Englebert - UNamur 13
Soient deux transactions T1 et T2 qui accèdent à deux ressources X et Y.
T1 ≡ [ W ← X ; Y ← 1 ]
T2 ≡ [ Z ← Y; X ← 2 ]
Alors que chaque opération a obtenu le
verrou correspondant, l’exécution
proposée à gauche ne correspond à
aucune sérialisation possible des deux
transactions proposées.
X Yr w rw
W ← X
Z ← Y
X ← 2
Y ← 1
T1 T2
X Yr w rw
X Yr w rw
X Yr w rw
X Yr w rw
X Yr w rw
T1;T2 T2;T1 E
X 2 2 2
Y 1 1 1
W X0 2 X0
Z 1 Y0 Y0
Le fait que T1 aie relaché le verrou en lecture sur X a permis à T2 de modifier la valeur de X.
X a donc une valeur « aléatoire » dans T1.
OR cette valeur est en contradiction avec les exécutions sérielles.
@ Vincent Englebert - UNamur 14
Le two-phase locking
Une transaction procède en deux phases
Phase 1: prendre des verrous sans en relacher
Phase 2: relacher des verrous sans en prendre
Nombredeverrousdétenus
t
Examinez le comportement de l’exemple précédent en
utilisant le 2-phase locking.
GOOD BAD
@ Vincent Englebert - UNamur 15
Le gestionnaire de verrous
Opérations
Lock(transaction id, ressource id, mode de verrou)
obtient si possible un verrou sur la ressource et sinon suspend l’exécution.
Unlock(transaction id, ressource id)
enlève le verrou préalablement posé par cette même transaction
Unlock(transaction id)
enlève tous les verrous d’une transaction (au commit par exemple).
Ressources Verrous posés en attente
x [T1,R] [T2,R] [T3,W]
y [T2,W] [T4,R],[T1,R]
z [T1,R]
Problèmes
ces opérations doivent être synchronisées !
Ces opérations sont invoquées pour chaque accès aux ressources
Risque d’embouteillage  bottleneck
~ 100 instructions machine !!!
@ Vincent Englebert - UNamur 16
Granularité
Plus la portée du verrou
sera petite
Moins il y aura de
conflits entre les
transactions
Cela augmente le nombre
de transactions qui
peuvent s’exécuter
simultanément
Plus le gestionnaire de
verrous sera sollicité
Sa structure de
données augmente,
+ d’appels,
+ de conflits entre les
appels (cfr.
synchronized)
Système
Base de données
TableLigne
champ
Exemples
SQL: la portée du verrou est généralement
la page.
plusieurs lignes bloquées pour 1!1! ligne
SGBD-OO: la portée du verrou est parfois
l’objet.
Granularité adaptive: le gestionnaire adapte
la granularité en fonction du comportement
de la transaction.
@ Vincent Englebert - UNamur 17
Deadlock
Un deadlock survient lorsque une transaction T1 nécessite une
ressource verrouillée par une autre transaction T2 et réciproquement.
Ressource Verrous en attente
x [T1,R] [T2,W]
y [T2,R] [T1,W]
Il suffirait que l’une des transactions relache un verrou pour débloquer la situation, mais c’est contraire au principe du 2-Phase Locking.
2 Solutions
Prévention des deadlocks (OS)
Réduction des deadlocks (TP moniteur)
Timeout-based detection
Graph-based detection
@ Vincent Englebert - UNamur 18
Timeout-based detection
Si les transactions durent moins de 15 secs, et qu’une transaction est
bloquée depuis Q secs (Q>15), alors faire un abort de cette
transaction.
Très simple à mettre en œuvre
ne détecte un deadlock qu’après 15 secs, alors que le deadlock a pu
apparaître à la première seconde: 14 secs perdues.
Peut interrompre une transaction qui n’est pas dans un deadlock.
Un transaction longue peut avoir du mal de résister à cette
technique.
@ Vincent Englebert - UNamur 19
Graph-based detection
Représenter les dépendances entre transactions dans un graphe et
analyser ce graphe de temps en temps.
T1
T2
T7
T9 T6
T3
T4
T8
T5
" a besoin d’un verrou posé par "
Exemple
Tant qu’il existe un cycle, interrompre la transaction qui bloque le plus d’autres transactions
ici T7 bloqueT9, T6, T3, T2, T1
@ Vincent Englebert - UNamur 20
Deadlocks distribués
From: Martin
To: Peggy
Qtt: 100
From: Peggy
To: Martin
Qtt: 200
Begin-Transaction
If (from.solde>=Qtt) {
from.debit(Qtt);
to.credit(Qtt);
}
End-transaction
T1,R,Martin
T1,W,Martin
T1,W,Peggy
T2,R,Peggy
T2,W,Peggy
T2,W,Martin
T2 T1 T2 T1
Martin Peggy
@ Vincent Englebert - UNamur 21
Performances
1% deadlock : pose peu de problèmes
Observations:
K: nombre de demandes d’écriture par transaction
D: nombre de ressources verrouillables
N: nombre de transactions simultanées
D
NK 2
)conflitP( =
2
4
)deadlockP(
D
NK
=
Source:Bernstein97/p207
@ Vincent Englebert - UNamur 22
Lock conversion
une transaction demande un verrou en lecture et demande ensuite de
commuter ce verrou en verrou en écriture.
Si deux transactions mettent à jour une même donnée en même temps,
cela aboutit à un deadlock, alors que si elles avaient demandé dès le
départ un verrou en écriture, il y aurait juste eu exclusion mutuelle,
blocage, mais pas de deadlock.
SQL
update CUSTOMER
set AGE=36
where NAME=« MARTIN » ;
L’analyseur SQL peut demander un verrou en écriture préventivement au
vu de cette requête. Plus difficile avec une BD OO et Java par exemple.
@ Vincent Englebert - UNamur 23
Arsenal
augmenter le nombre de verrous, i.e., diminuer la granularité
pour une table, faire un partitionnement vertical
D
NK 2
)conflitP( =2
4
)deadlockP(
D
NK
=
Produit
code
nom
description
taille
prix
en-stock
seuil-commande
abimés
id: code
1-1 1-1Pro_Pro
Produit
en-stock
seuil-commande
abimés
Produit
code
nom
description
taille
prix
id:code
Produit_stock
code
en-stock
seuil-commande
abimés
id: code
equ
Produit
code
nom
description
taille
prix
id: code
On augmente D !
Essentiellement lecture de produit
pour générer le catalogue on-line
Mises-à-jour concentrées sur
Produit_stock. Sans interférence
avec Produit.
@ Vincent Englebert - UNamur 24
Techniques d’optimisation
Écourter au maximum la durée de vie des verrous
Postposer les opérations juste avant la conclusion de la transaction
Begin-transaction
for cli in file_clients do {
if read(cli.solde)>100.000 then write(cli.credit,true)
else write(cli.credit,false);
}
End-transaction
read(line 4125.solde)
write(line 4125.credit,true)
read(line 9547.solde)
write(line 9547.credit,false)
read(4125.solde)
write(4125.credit,true)
read(9547.solde)
write(9547.credit,false)
256.325
26.782
Read only
Replay and write iff success
Read and write
@ Vincent Englebert - UNamur 25
Degree isolation 2 / cursor stability
Affaiblir les exigences d’une transaction
dans l’aide à la décision, de nombreuses requêtes calculent des ratios, des
indices, des sommes, …
Pour ces requêtes, l’idée est de poser un verrou en lecture juste pendant la
lecture de chaque donnée et de le relâcher après.
Begin-transaction-molle
Somme:=0
For cli in file-clients do {
lock(cli.solde,read);
X:=read(cli.solde);
unlock(cli.solde);
Somme:=Somme+X;
}
End-transaction-molle
Begin-transaction
write(6000.solde,66€)
write(6002.solde,44€)
End-transaction
Les transactions sont encore sérialisables, mais ces queries ne peuvent garantir l’exactitude du résultat.
Certains utilisateurs s’en accommodent néanmoins.
viole le principe du 2P locking
Exécution de cette
transaction en
plein milieu de
l ’autre.
Entre deux
itérations,
cette
« transacti
on » ne
possède
aucun
verrou.
@ Vincent Englebert - UNamur 26
Degree isolation 1 / dirty reads
Aucun lock durant la lecture d’une information.
On peut dont lire des données qui ne devraient pas exister!
Exemple
Begin-transactionBegin-transaction
/* lock(cli,écriture) */
write(cli.national,keyboard())
while not isletter(read(cli.national))
do{
write(cli.national,keyboard());
}
/* unlock(cli) */
End-transactionEnd-transaction
Print(read(cli.nom));
Print(read(cli.national));
cette "transaction" travaille en ignorant
la valeur des locks des ressources qu'elle
utilise
« Durant » « # »
affiche
@ Vincent Englebert - UNamur 27
Intention lock / intention de verrouillage
Un intention lock est un pseudo-verrou que l’on pose sur une
ressource composite afin de marquer l’intention de verrouiller un
composant de ce dernier.
Intention
Lecture
Lecture
Intention
Écriture
Écriture
Intention
Lecture
+ + + -
Lecture + + - -
Intention
Écriture
+ - + -
Écriture - - - -
On pose un « intentional lock » sur une ressource composite lorsqu'une transaction souhaite déposer un lock
sur un de ses composants.
Le fait de raisonner sur des locks « agrégés » évite de fastidieuses vérifications sur des locks indivuels.
@ Vincent Englebert - UNamur 28
Banque
NamurTournai
Dupont Martin
#125
#126 #127
#124
#123
T1: somme des avoirs de Monsieur Duchemin
T2: transfert entre dupont et martin: #123→#126
T3: listing des clients de Tournai
IR
R
IW
IW
W W
IR
Comparer cette configuration avec
un modèle sans « intention locks ».
Duchemin
#128 #129
IW
IR IW R
exclusionexclusion
T1 et T3 peuvent s'exécuter en
concurrence. Test de deux
locks uniquement!
Il y a exclusion entre T2 et T3
 T1 et T2 peuvent s'exécuter en
concurrence si les comptes sont
disjoints (c'est le cas ici).
 Coût: gérer les
locks sur la hauteur
d'une arborescence.
@ Vincent Englebert - UNamur 29
Gestion de la concurrence entre transactions
La gestion de la concurrence avec des verrous pose certains
problèmes:
La gestion des verrous constitue un overhead non négligeable, même
lorsque les transactions ne se menacent pas entre elles.
L'utilisation de verrous provoque des deadlocks qu'il faut gérer soit par
détection soit avec une technique de timeout.
Puisque les verrous ne peuvent être relâchés avant la fin de la transaction,
cela réduit les possibilités d'exécutions concurrentes.
Usage parfois trop pessimiste des verrous
Begin-transaction
lock(x,y);
if (condition) x:=1 else y:=1
unlock(x,y);
end-transaction
Dans les faits, les conflits sont assez rares
Déplacer la gestion du problème lorsqu'il y a conflit uniquement.
On laisse s'exécuter les transactions (sans poser de verrous!) et on
examine le risque de conflit à la fin, avant de conclure la transaction.
Begin-transaction
assert x==1
x:=1
end-transaction
@ Vincent Englebert - UNamur 30
Sérialisation des transactions
Cfr. Slides LaTeX
(sérialisation des transactions)
@ Vincent Englebert - UNamur 31
Le Protocole Two-Phase Commit
Lorsqu’une transaction concerne plusieurs gestionnaires de
ressources, comment synchroniser ceux-ci pour que tous exécutent la
transaction ou aucun ?
Un gestionnaire de ressources peut tomber en panne
le coordinateur peut tomber en panne
Le réseau de communication peut être défectueux
Gestionnaire
Ressources
Gestionnaire
Ressources
Gestionnaire
Ressources
Gestionnaire
Ressources
Gestionnaire
Ressources
Gestionnaire
Ressources
CoordinateurCoordinateur
@ Vincent Englebert - UNamur 32
HypothèsesHypothèses
Une transaction provoque un abort si elle rencontre un problème, et provoque un
commit sinon. Cela mettra en œuvre le protocole 2PC .
Chaque gestionnaire de ressources peut faire un commit ou un abort de la partie de la
transaction qui le concerne.
Un seul programme ordonne l’ordre commit. Si plusieurs ordres commit étaient lancés
durant le 2PC, un gestionnaire pourrait faire un commit alors qu’un autre ferait un abort.
Nous sommes dans un environnement distribué, plusieurs programmes peuvent
être impliqués dans la transaction et donc lancer indépendamment l'ordre commit
ou abort.
Lorsque l’ordre commit est lancé, les opérations impliquées dans la transaction doivent
être terminées sur tous les gestionnaires.
Tâche exécutée de manière synchrone: pas de problème
Tâche exécutée de manière asynchrone: travail supplémentaire pour s’assurer de la
fin de l’exécution. Exemple:
module { onewayoneway void do_something(); … }
begin_transaction();
object_remote.do_something();
commit();
Le système n’a pas de comportement frauduleux, il fait ce qu’il dit qu’il fait.
Les composants utilisent un timeout pour décider qu’un autre composant est en panne
ou que le réseau est défectueux .
Les serveurs et réseaux fonctionnent dfe temps en temps, au moins !
@ Vincent Englebert - UNamur 33
Les deux phasesLes deux phases
Phase 1
s’assurer que chaque gestionnaire est prêt à faire un commit.
Exemple:
toutes les informations pour mettre à jour la BD sont disponibles et stockées en
lieu sûr.
Si le gestionnaire tombe en panne alors qu’il a dit qu’il était prêt, il s’engage à
avoir assez d’informations pour retrouver l’état d’avant la panne.
Phase 2
le coordinateur initie le commit sur chaque gestionnaire
Coordinateur Gestionnaire Gestionnaire Gestionnaire
request-to-prepare
prepared
commit
done DONE:
la requête
a été reçue
DONE:
la requête
a été reçue
@ Vincent Englebert - UNamur 34
Coordinateur Gestionnaire Gestionnaire Gestionnaire
request-to-prepare
prepared
abort
done
prepared
no
@ Vincent Englebert - UNamur 35
Les moments entre lesquels un gestionnaire émet le message
« prepared » et reçoit la requête « abort » ou « commit » est appelée
« période d’incertitude ».
Le gestionnaire ne peut prendre aucune initiative durant cette période. Si le
coordinateur ou le réseau a une défaillance, le gestionnaire est bloqué.
Les acteurs (gestionnaires & coordinateur) utilisent un système de log
fiable. Le demande d'écriture rend la main lorsque l'information est
écrite définitivement.
ThéorèmeThéorème
Pour tout protocole de commit distribué (et pas seulement ceux à
deux-phases), une défaillance de communication peut laisser un
gestionnaire dans un état bloqué.
@ Vincent Englebert - UNamur 36
Gestion des échecs de transmissionGestion des échecs de transmission
Point de vue du coordinateurcoordinateur
émission du message « request-to-prepare »
on envoie une bouteille à l’eau, rien de grave ne peut se passer
réception des messages « prepared » et/ou « no »
si l’un des gestionnaires ne répond pas endéans le timeout, on considère qu’il a
envoyé le message « no ».
Si un ou plusieurs messages « no » sont reçus, alors le coordinateur
provoque un abort.
Émission du message « commit » ou « abort » .
on envoie une bouteille à l’eau, rien de grave ne peut se passer
Réception du message « done » des gestionnaires
si un message n’est pas reçu, alors attendre plus longtemps ou réveiller le
gestionnaire en renvoyant le dernier message (commit ou abort)
@ Vincent Englebert - UNamur 37
Du point de vue du gestionnairegestionnaire
Réception du message « request-to-prepare »
après voir fait le job requis par la transaction, si le gestionnaire ne reçoit pas ce
message endéans le timeout, il décide d’avorter la transaction. Il restera
silencieux, ce qui revient au même qu’un message « no ».
Émettre un message « prepared » ou « no » selon que la préparation s’est
bien passée ou non.
⇒ Pas de problèmes.
Réception du « commit » ou « abort »
on est dans la période d’incertudepériode d’incertude.
Le gestionnaire ne peut prendre aucune initiative.
Émettre le message « done ».
⇒ Pas de problèmes.
@ Vincent Englebert - UNamur 38
Gestion des crashesGestion des crashes
Écrire la liste des gestionnaires
participant à la transaction dans le Log.
Écrire le mot commit/abort dans le
Log.
Écrire le mot done dans le log.
Aucun message n'a été envoyé aux
gestionnaires.
Aucun gestionnaire n’a reçu le message
commit. Un no a été reçu ou un
prepared n'a pas été reçu endéans le
timeout. Le coordinateur décide
d’avorter la transaction. De leur côté,
certains gestionnaires ont peut-être déjà
avorté la transaction.
Si on ne reçoit pas le message done
endéans le timeout, on réémet le
message du log-file. Attente
éventuellement infinie.
Tout a été fait dans les règles. Il n’y a
rien à faire, la transaction est
clôturée.
GestionnaireGestionnaireCoordinateur Gestionnaire
request-to-prepare
prepared|no
Commit|abort
done
log(start;G1,G2,…,Gn)
log(commit/abort)
log(done)
1.
2.
3.
4.
log(prepared|no)
log(committed/aborted)
A.
B.
C.
@ Vincent Englebert - UNamur 39
Gestion Crash Coordinateur
CRASH PHASE 1
Rien n'a été entrepris. Pas de problème donc.
CRASH PHASE 2
Quand le coordinateur est "réanimé", il trouve le mot "start" et la liste
des gestionnaires dans le log file.
Si le gestionnaire avait commencé à recevoir des messages des
gestionnaires, ils sont perdus.
Réémettre le message "request-to-prepare" aux gestionnaires.
CRASH PHASE 3
Renvoyer le message trouvé dans le log file ("commit" ou "abort")
CRASH PHASE 4
Si le coordinateur trouve le mot "done" dans le log file, il peut se
reposer.
@ Vincent Englebert - UNamur 40
Écrire le mot prepared dans le Log
quand toutes les informations
nécessaire à un recovery ont été
préservées et que l’on a reçu le
message request-to-prepare
Écrire le mot committed ou
aborted dans le log.
A On ne reçoit pas de request-to-prepare
endéans le timeout après avoir préparé
la transaction locale. Le gestionnaire
peut décider d'avorter. Il suffira ne pas
envoyer le message prepared ou de
répondre no à la l'éventuelle prochain
message request-to-prepare.
B L’information pour faire un recovery est
disponible: le gestionnaire peut
faire un commit s'il reçoit un commit
faire un abort s'il reçoit un abort
n’avoir rien reçu (période d'incertitude)(période d'incertitude)
 Essayer de rétablir la communication
avec le coordinateur, intervention
manuelle, …
C On n'attend aucun message, il suffit de
terminer la transaction locale (confiée au
SGBD par exemple) et de renvoyer
done.
 pas de problèmes donc.
GestionnaireGestionnaireCoordinateur Gestionnaire
request-to-prepare
prepared | no
Commit|abort
done
log(start)
log(commit | abort)
log(done)
1.
2.
3.
4.
log(prepared|no)
log(committed | aborted)
A.
B.
C.
@ Vincent Englebert - UNamur 41
Gestion Crash Gestionnaire
CRASH PHASE A
Le gestionnaire trouve le log file vide: les informations à propos de la
transaction n'ont peut-être pas pu être mis en lieu sûr: il décide de se
saborder:
répondre no au prochain "request-to-prepare"
ou ne pas répondre.
CRASH PHASE B
Les informations sur la transaction locale sont en lieu sûr. Le
gestionnaire attend l'ordre "commit"  ou "abort" du coordinateur. (il
l'avait peut-être déjà reçu et donc perdu…).
période d'incertitude
CRASH PHASE C
Renvoyer le message "done" au coordinateur.
@ Vincent Englebert - UNamur 42
Transactions imbriquées
Une transaction imbriquée est un arbre de transactions qui sont elles-
mêmes imbriquées ou simples.
Les transactions aux feuilles de l'arbre sont des transactions simples
Une transaction fille peut faire soit un commit ou un abort.
Le commit n'a d'effet que si le parent fait aussi un commit (et ainsi de
suite).
En attendant, les résultats du commit ne sont visibles que des transactions
parentes (directes ou indirectes)
un abort (i.e. rollback) entraîne l'annulation de toutes les transactions filles
de celle-ci (qu'elles aient fait un commit ou pas!).
ACID : les transactions imbriquées dans d'autres transactions ne sont pas
durables! Mais la racine l'est!
Les objets détenus par une transaction mère sont accessibles aux
transactions filles.
Si deux transactions filles s'exécutent en parallèle, les effets de l'une
ne sont pas visibles de l'autre et récipr. : Isolation
@ Vincent Englebert - UNamur 43
T1,1 T1,2
T1,1,1 T1,1,2
T1
T1,2,2
begin
transaction commit
1←x
1=x
0=x0=x 1=x
Roll-back
@ Vincent Englebert - UNamur 44
T1,1 T1,2
T1,1,1 T1,1,2
T1
T1,2,2
begin
transaction
1←x
1=x
0=x0=x 0=x
Roll-back
@ Vincent Englebert - UNamur 45
@ MSDN
Nested Transactions
A nested transaction occurs when a new transaction is started on a session that is already inside the
scope of an existing transaction. The new, nested transaction is said to be nested within (or below
the level of) the existing transaction. Changes made within the nested transaction are invisible to the
top-level transaction until the nested transaction is committed. Even then, the changes are not visible
outside the top-level transaction until that transaction is committed. Providers that expose
ITransactionLocal and support nested transactions can choose to support only a limited number of
nested transactions, including zero.
For providers that support nested transactions, calling ITransactionLocal::StartTransaction on a
session with an existing transaction begins a new transaction nested below the current transaction.
The return level indicates the level of nesting: a return value of 1 indicates a top-level transaction
(that is, a transaction that is not nested within another transaction); 2 indicates a second-level
transaction (a transaction nested within a top-level transaction); and so on.
Each nested transaction is represented by a transaction object.
Calling ITransaction::Commit or ITransaction::Abort on the session object commits or aborts the
transaction at the current (lowest) nesting level. Calling Commit or Abort on a transaction object
nested at a given level commits or aborts the transaction at that nesting level. Committing or aborting
a transaction commits or aborts all transactions nested below it as well.
Calling ITransaction::Commit or ITransaction::Abort on a transaction object with the fRetaining
flag set to TRUE implicitly begins a new unit of work, and the transaction object remains valid. Calling
Commit or Abort with fRetaining set to FALSE terminates the transaction, and the transaction object
enters a zombie state. At this point, the only valid action that can be performed on the transaction
object is to release it.
Before the resources used by a transaction object can be freed by the provider, the transaction object
and all transaction objects nested below it must be released. Releasing a transaction object aborts
any uncommitted work performed in that transaction.
@ Vincent Englebert - UNamur 46
@ENCINA from IBM
Nested and top-level transactions
As described in the previous section, a nested transaction is begun within the scope of another transaction. The transaction
that starts the nested transaction is called the parent of the nested transaction. There are two types of nested transactions:
• A nested top-level transaction commits or aborts independently of the enclosing transaction. That is, after it is
created, it is completely independent of the transaction that created it. The Tran-C topLevel construct for creating
nested top-level transactions. The syntax of this construct is identical to that of the transaction construct, but the
topLevel keyword is used instead of the transaction keyword.
• A nested subtransaction commits with respect to the parent transaction. That is, even though the subtransaction
commits, the permanence of its effects depends on the parent transaction committing. If the parent transaction aborts,
the results of the nested transaction are backed out. However, if the nested transaction aborts, the parent transaction is
not aborted. The easiest way to create a nested subtransaction transaction in Tran-C is to simply use a transaction
block within the scope of an existing transaction. Tran-C automatically makes the new transaction a subtransaction of
the existing transaction.
In this chapter, when we discuss nested transactions, we are generally referring to nested subtransactions unless we specify
otherwise.
A series of nested subtransactions is viewed as a hierarchy of transactions. When transactions are nested to an arbitrary
depth, the transaction that is the parent of the entire tree (family) of transactions is referred to as the top-level transaction. If
the top-level transaction aborts, all nested transactions are aborted as well.
By default, nested subtransactions of the same parent transaction are executed sequentially within the scope of the parent.
The Tran-C concurrent and cofor statements can be used to create subtransactions that execute concurrently with each other
on behalf of their parent transaction. For more information, see the Encina Transactional Programming Guide.
@ Vincent Englebert - UNamur 47
@ENCINA from IBM
error_status_t OrderItem(idl_ulong_int stockNum,
idl_ulong_int numOrdered,
idl_ulong_int customerId)
{
idl_long_int returnStatus;
idl_long_int costPerItem, totalCost;
short priority;
volatile short preferredCustomer = TRUE;
transaction{
PlaceOrder(stockNum, numOrdered, &costPerItem);
totalCost = numOrdered * costPerItem;
if (totalCost > 1000)
priority = HIGH_PRIORITY;
else
priority = NORMAL_PRIORITY;
PlaceItemOnQueue(stockNum, numOrdered,
customerId, priority);
transaction{/* Begin a nested transaction. */
          BillPreferredCustomer(customerId, totalCost);
} onAbort {
/* If nested transaction aborts. */
preferredCustomer = FALSE;
}
/* If nested transaction aborted, check mainframe database */
if (!preferredCustomer)
     BillForItem(customerId, totalCost);
}onCommit{
fprintf(stderr, "We committed.n");
return SUCCESS;
}onAbort{
fprintf(stderr, "We aborted. %sn", abortReason());
return ORDER_FAILED;
}
}
@ Vincent Englebert - UNamur 48
Le modèle X/OpenLe modèle X/Open
X/Open a défini un ensemble de
passerelles pour que des
technologies hétérogènes puissent
être utilisées dans des applications
transactionnelles.
TX: définit l'interface entre une
application et le gestionnaire de
transactions.
Exemple
tx_begin, tx_commit, tx_rollback,
tx_open, tx_close,
tx_info,tx_set_commit_return,
tx_set_transaction_timeout
XA: définit l'interface entre le
coordinateur de transactions et le
gestionnaire de ressources
Programme d'applicationProgramme d'application
Gestionnaire de
ressources
Gestionnaire de
ressources
Gestionnaire de
ressources
Gestionnaire de
ressources
Gestionnaire de
ressources
Gestionnaire de
ressources
Coordinateur de TransactionsCoordinateur de Transactions
TX interface
start, commit, abort
XA interface
2PC operations
SQL
JDBC
ODBC
ISAM
...
@ Vincent Englebert - UNamur 49
Exemple: XA-protocole
@ Vincent Englebert - UNamur 50
Les Transactions et CORBA
OTS (Object Transaction Service)
OTS est une description en termes OO (i.e. IDL) de l'architecture
décrite par l'X/Open.
Transactions imbriquées
Transactions distribuées
Gestion des transactions implicites (ou non)
Propagation des transactions contrôlées par le programmeur
Portabilité (i.e. indépendance % technologie du TP moniteur)
Support d'applications multi-thread (client & serveur)
Performances similaires à l'X/Open procédural (en termes de messages
émis sur le réseaux)
Interopérabilité avec d'autres systèmes (X/Open)
@ Vincent Englebert - UNamur 51
@ Vincent Englebert - UNamur 52
Transaction dans un exemple 3-tiers
Client
Transactionnel
Client
Transactionnel
Objet
Transactionnel
Objet
Récupérable
Serveur
Transactionnel
Serveur
Récupérable
Service de Transactions
Contexte de
Transaction
begin
commit
roll-back roll-back
register
roll-back
2PC Protocole
ClientClientClientClient BusinessBusinessBusinessBusiness RepositoryRepositoryRepositoryRepository
RessourceRessource
Ressource
@ Vincent Englebert - UNamur 53
@ Vincent Englebert - UNamur 54
Les concepts
Client Transactionnel
Programme pouvant invoquer des opérations sur des objets transactionnels dans une
transaction.
Objet Transactionnel
Objet dont le comportement est affecté par le fait de participer à une transaction. Un
objet peut assumer la transaction pour certaines requêtes et pas pour d'autres, ce
comportement est dynamique.
Objet Récupérable (recoverable)
Objet dont les données sont affectées par l'issue (commit | rollback) d'une transaction.
Un objet récupérable est un objet transactionnel.
Un objet récupérable participe au protocole de gestion de la transaction en enregistrant
un objet « ressource » auprès du service de transaction.
Le service de transaction coordonne la transaction en dialoguant avec les ressources.
Serveur Transactionnel
Collection d'un ou plusieurs objets transactionnels (objets récupérables exclus). Ce
serveur n'est pas impliqué par la clôture des transactions mais peut provoquer un
rollback.
Serveur Récupérable (recoverable)
Collection d'objets transactionnels dont un au moins est récupérable.
Il participe au protocole en enregistrant des ressources. Le service de transaction gère la
transaction en dialoguant avec les ressources enregistrées.
@ Vincent Englebert - UNamur 55
Types de transactions
Le Service Transactions de CORBA fournit les interfaces pour gérer
des transactions plates (requis)
des transactions imbriquées (en option)
Une transaction est clôturée par le client transactionnel qui est à son
origine
certaines implémentations peuvent déroger à cette règle
N'importe quel composant intervenant dans une transaction peut
provoquer un rollback.
le composant a un problème impossible de faire le commit
DB,
disque en panne,
manque de ressources,
…
conditions non satisfaites
Sécurité
Annulation de l'opérateur
…
@ Vincent Englebert - UNamur 56
InterfaceInterface ControlControl
Représente le concept de transaction (simple ou imbriquée). Comme pour tout autre objet
distribué, on utilise un factory pour créer un objet Control.
Terminator get_terminator(…);
Coordinator get_coordinator();
Interface TransactionFactoryInterface TransactionFactory
Factory pour créer des objets de type Control.
Control create(in unsigned long tiime_out)
Interface TerminatorInterface Terminator
void commit(…);
void rollback();
Interface CoordinatorInterface Coordinator
Fournit les opérations requises pour enregistrer les ressources impliquées par le protocole
2PC.
RecoveryCoordinator register_ressource(in Resource)
Interface ResourceInterface Resource
Décrit le comportement d'un objet considéré comme une ressource pour le 2PC scénario.
Exemple: gérer un fichier texte comme une ressource !!!
Vote prepare();Vote prepare();
void rollback();void rollback();
void commit();void commit();
void commit_one_phase();void commit_one_phase();
void forget();void forget();
fr:ressource
en:resource
@ Vincent Englebert - UNamur 57
Interface CurrentInterface Current
Associé à tout objet qui hérite de l'interface TransactionalObject.
Représente la transaction courante durant l'invocation de l'opération.
Sa valeur est gérée par le POA.
Permet d’obtenir la référence du « Control ».
Un current par thread.
void begin();void begin();
void commit(in boolean report);void commit(in boolean report);
void rollback();void rollback();
Control get_control();Control get_control();
@ Vincent Englebert - UNamur 58
Programmation expliciteProgrammation explicite
le programmeur doit gérer explicitement la transaction
créer une transaction (Control)
passer le Control comme paramètre de l'opération
et ainsi de suite.
R1 R3R2
O1O1 O2O2 O3O3Client
C:Contro
l
O4O4
C
C
C
Certaines méthodes peuvent être soumises à une transaction et d'autres pas
Exemple
Mise à jour de la base de données  oui [update_db(info,control)]
Mise à jour du fichier d'audit trail  non [update_log(info)]
l'instance qui initie la transaction ne doit pas nécessairement être celle qui la
termine (abort/commit).
Exemple (workflow)
pas nécessairement supporté par tous les OTS.
Saisie Mise-à-jourvérification
Approuver
& imprimer
begin
abort/commit abort/commit
abort/commit
@ Vincent Englebert - UNamur 59
Programmation impliciteProgrammation implicite
tout type d'objet qui participe à une transaction doit hériter de
CosTransactions::TransactionalObject.
Cette interface est vide et constitue juste une astuce qui permettra à l'ORB de gérer
les objets de ce type comme des objets transactionnels.
L'ORB associe systématiquement un Control avec les méthodes de ces objets.
CORBA fournit une pseudo-interface qui décrit un objet utilitaire pour faciliter la
programmation des transactions.
boolean commit=true;
try {
CosOTS::Current::begin();
[…]
compte.transfert(compte_to,10000);
CosOTS::Current::commit();
}
catch (CORBA::TRANSACTION_ROLLBACK){
cosOTS::Current::rollback();
System.out.println(« Rollback exception, opération avortée »);
commit=false;
}
catch (...){
cosOTS::Current::rollback();
System.out.println(« exception bizarre!  rollback »);
commit=false;
}
if (commit) {
System.out.println(« opération réussie »);
}
@ Vincent Englebert - UNamur 60
module CosTransactions {
enum Status { StatusActive, StatusMarkedRollback, StatusPrepared, StatusCommitted,
StatusRolledBack, StatusUnknown, StatusNoTransaction, StatusPreparing, StatusCommitting,
StatusRollingBack };
enum Vote { VoteCommit, VoteRollback, VoteReadOnly };
struct TransIdentity {
Coordinator coord;
Terminator term;
otid_t otid;
};
struct PropagationContext {
unsigned long timeout;
TransIdentity current;
sequence <TransIdentity> parents;
any implementation_specific_data;
};
local interface Current : CORBA::Current {
void begin() raises(SubtransactionsUnavailable);
void commit(in boolean report_heuristics)
raises(NoTransaction,HeuristicMixed,HeuristicHazard);
void rollback() raises(NoTransaction);
void rollback_only() raises(NoTransaction);
Status get_status();
string get_transaction_name();
void set_timeout(in unsigned long seconds);
Control get_control();
Control suspend();
void resume(in Control which) raises(InvalidControl);
};
@ Vincent Englebert - UNamur 61
interface TransactionFactory {
Control create(in unsigned long time_out);
Control recreate(in PropagationContext ctx);
};
interface Control {
Terminator get_terminator() raises(Unavailable);
Coordinator get_coordinator() raises(Unavailable);
};
interface Terminator {
void commit(in boolean report_heuristics) raises(HeuristicMixed,HeuristicHazard);
void rollback();
};
@ Vincent Englebert - UNamur 62
interface Coordinator {
Status get_status();
Status get_parent_status();
Status get_top_level_status();
boolean is_same_transaction(in Coordinator tc);
boolean is_related_transaction(in Coordinator tc);
boolean is_ancestor_transaction(in Coordinator tc);
boolean is_descendant_transaction(in Coordinator tc);
boolean is_top_level_transaction();
unsigned long hash_transaction();
unsigned long hash_top_level_tran();
RecoveryCoordinator register_resource(in Resource r) raises(Inactive);
void register_synchronization (in Synchronization sync) raises(Inactive, SynchronizationUnavaila
void register_subtran_aware(in SubtransactionAwareResource r) raises(Inactive, NotSubtransaction
void rollback_only() raises(Inactive);
string get_transaction_name();
Control create_subtransaction() raises(SubtransactionsUnavailable, Inactive);
PropagationContext get_txcontext () raises(Unavailable);
};
interface RecoveryCoordinator {
Status replay_completion(in Resource r) raises(NotPrepared);
};
interface Resource {
Vote prepare() raises(HeuristicMixed,HeuristicHazard);
void rollback() raises(HeuristicMixed,HeuristicHazard);
void commit() raises(NotPrepared,HeuristicRollback,HeuristicMixed,HeuristicHazard);
void commit_one_phase() raises(HeuristicHazard);
void forget();
};
@ Vincent Englebert - UNamur 63
interface TransactionalObject {};
interface Synchronization : TransactionalObject {
void before_completion();
void after_completion(in CosTransactions::Status status);
};
interface SubtransactionAwareResource : Resource {
void commit_subtransaction(in Coordinator parent);
void rollback_subtransaction();
};
};
@ Vincent Englebert - UNamur 64
Vue d'ensemble du module OTS
Terminator
commit
rollback
Coordinator
register_resource
Resource
vote prepare
void rollback
void commit
Control
coordinateur: *Coordinator
terminateur: *Terminator
Terminator get_terminator
Coordintaor get_coordinator
Current
context: *Control
void begin
void commit
void rollback
Control get_control
TransactionFactory
Control create
@ Vincent Englebert - UNamur 65
:CoordinatorFrom:account
(Resource)
To:Account
(Resource)
:CurrentClient:App.exe
begin()
debit(100)
credit(100)
get_control()
register_resource()
get_control()
register_resource()
commit()
commit()
commit()
prepare()
prepare()
From:account :XADataStore To:Account :XADataStore :CoordinatorClient:App.exe
Begin()
Commit()
Debit(100)
Credit(100)
Register_resource()
Xa_start()
Read/write()
Xa_end()
Register_resource()
Xa_start()
Read/write()
Xa_end()
Vote()
Xa_start()
Write modified data
Xa_end
Xa_prepare
Xa_start()
Write modified data
Xa_end
Xa_prepare
Vote()
doCommit()
doCommit()
Xa_commit()
Xa_commit()
@ Vincent Englebert - UNamur 67
Exemple: transfert bancaireExemple: transfert bancaire
#include <CosTransactions.idl>
module WithResource{
interface AccountResource : CosTransactions::Resource {
float balance();
void credit( in float value );
void debit( in float value );
};
interface Account : CosTransactions::TransactionalObject{
float balance();
void credit( in float value );
void debit( in float value );
};
exception NotExistingAccount
{ };
interface Bank {
Account create_account( in string name );
Account get_account( in string name )
raises( NotExistingAccount );
};
};
@ Vincent Englebert - UNamur 68
class Client {
void main(){
org.omg.CosTransactions.Current current = null;
org.omg.CORBA.Object obj = _orb.resolve_initial_references("TransactionCurrent");
current = org.omg.CosTransactions.CurrentHelper.narrow( obj );
current.begin();
Account supplier = _bank.get_account( name_supplier );
Account consumer = _bank.get_account( name_consumer );
supplier.debit( famount );
consumer.credit( famount );
current.commit( false );
}
}
Le code de cette application a été nettoyé des instruction de traitement d'exception.
On suppose que le client a déjà résolu les diverses références vers ses objets distants.
@ Vincent Englebert - UNamur 69
package WithResource;
public class BankServer {
public static void main( String [] args ) {
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
org.omg.CORBA.Object objPoa = null;
org.omg.PortableServer.POA rootPOA = null;
objPoa = orb.resolve_initial_references("RootPOA");
rootPOA = org.omg.PortableServer.POAHelper.narrow(objPoa);
BankImpl bank = new BankImpl( orb );
byte[] servantId=rootPOA.activate_object(bank);
org.omg.CORBA.Object obj=rootPOA.id_to_reference(servantId);
String reference = orb.object_to_string(obj);
java.io.FileOutputStream file = new java.io.FileOutputStream("ObjectId");
java.io.PrintStream pfile=new java.io.PrintStream(file);
pfile.println(reference);
file.close();
rootPOA.the_POAManager().activate();
System.out.println("The bank server is now ready...");
orb.run();
}
}
@ Vincent Englebert - UNamur 70
package WithResource;
public class BankImpl extends BankPOA {
private java.util.Hashtable _accounts;
private org.omg.CORBA.ORB _orb;
public BankImpl( org.omg.CORBA.ORB orb ) {
_accounts = new java.util.Hashtable();
_orb = orb;
}
public Account create_account( String name ) {
AccountImpl acc = new AccountImpl( name );
_poa().activate_object(acc);
_accounts.put( name, acc );
return acc._this( );
}
public Account get_account( String name )
throws NotExistingAccount
{
AccountImpl acc = ( AccountImpl ) _accounts.get( name );
if ( acc == null ) {
throw new NotExistingAccount();
}
return acc._this();
}
}
@ Vincent Englebert - UNamur 71
package WithResource;
public class AccountImpl extends AccountPOA
{
float _balance;
private org.omg.CORBA.ORB _orb;
java.util.Vector _resources;
private String _name;
public AccountImpl( org.omg.CORBA.ORB orb, String name ){
_balance = 0;
_orb = orb;
_resources = new java.util.Vector();
_name = name;
}
public float balance() {
return get_resource().balance();
}
public void credit( float value ) {
get_resource().credit( value );
}
public void debit( float value ) {
get_resource().debit( value );
}
public void rollbackOnly() {
CORBA.Object obj = _orb.resolve_initial_references("TransactionCurrent");
CosTransactions.Current current = CosTransactions.CurrentHelper.narrow( obj );
current.rollback_only();
}
à suivre ...
@ Vincent Englebert - UNamur 72
...
public AccountResource get_resource() {
org.omg.CORBA.Object objPoa = null;
org.omg.PortableServer.POA rootPOA = null;
CORBA.Object obj = _orb.resolve_initial_references("TransactionCurrent");
CosTransactions.Current current = CosTransactions.CurrentHelper.narrow( obj );
CosTransactions.Coordinator coordinator = current.get_control().get_coordinator();
AccountResourceImpl resource = null;
for ( int i=0; i<_resources.size(); i++ ) {
resource = ( AccountResourceImpl ) _resources.elementAt( i );
if ( coordinator.is_same_transaction( resource.coordinator() ) )
return resource._this( );
}
System.out.println("Create a new resource for " + _name );
resource = new AccountResourceImpl( _poa(), coordinator, this, _name );
objPoa = _orb.resolve_initial_references("RootPOA");
rootPOA = org.omg.PortableServer.POAHelper.narrow(objPoa);
rootPOA.activate(resource)
AccountResource res = resource._this();
coordinator.register_resource( res );
_resources.addElement( resource );
return res;
}
}
@ Vincent Englebert - UNamur 73
package WithResource;
public class AccountResourceImpl extends AccountResourcePOA{
private float _initial_balance;
private float _current_balance;
private CosTransactions.Coordinator _coordinator;
private AccountImpl _account;
private String _name;
private PortableServer.POA _poa;
public AccountResourceImpl( PortableServer.POA poa,
CosTransactions.Coordinator coordinator,
AccountImpl account, String name ) {
_coordinator = coordinator;
_name = name;
_poa = poa;
_account = account;
_initial_balance = account._balance;
_current_balance = _initial_balance;
}
public float balance() {
return _current_balance;
}
public void credit( float value ) {
_current_balance += value;
}
public void debit( float value ) {
_current_balance -= value;
}
à suivre ...
@ Vincent Englebert - UNamur 74
...
public CosTransactions.Vote prepare() {
System.out.println("[ Resource for " + _name + " : Prepare ]");
if ( _initial_balance == _current_balance ) {
// No change
removeItself();
return CosTransactions.Vote.VoteReadOnly;
}
if ( _current_balance < 0 ) {
removeItself();
return CosTransactions.Vote.VoteRollback;
}
return CosTransactions.Vote.VoteCommit;
}
public void rollback() {
System.out.println("[ Resource for " + _name + " : Rollback ]");
removeItself();
}
public void commit() {
System.out.println("[ Resource for " + _name + " : Commit ]");
_account._balance = _current_balance;
removeItself();
}
public void commit_one_phase() {
System.out.println("[ Resource for " + _name + " : Commit one phase ]");
_account._balance = _current_balance;
removeItself();
}
à suivre ...
@ Vincent Englebert - UNamur 75
public void forget() {
System.out.println("[ Resource for " + _name + " : Forget ]");
removeItself();
}
public CosTransactions.Coordinator coordinator() {
return _coordinator;
}
private void removeItself() {
_account._resources.removeElement( this );
_poa.deactivate_object( _poa.servant_to_id( this ) );
}
}
FIN

Weitere ähnliche Inhalte

Andere mochten auch

Diaporama nture 2
Diaporama nture 2Diaporama nture 2
Diaporama nture 2Saqqarah 31
 
Carnet De Bord PôLe Technique
Carnet De Bord PôLe TechniqueCarnet De Bord PôLe Technique
Carnet De Bord PôLe Techniqueguest0ed19c
 
Restful, really ? MixIt 2014
Restful, really ? MixIt 2014Restful, really ? MixIt 2014
Restful, really ? MixIt 2014Xavier Carpentier
 
Ies isabel perillan 2009 10 frances 3 eso - musee d orsay
Ies isabel perillan 2009 10 frances 3 eso - musee d orsayIes isabel perillan 2009 10 frances 3 eso - musee d orsay
Ies isabel perillan 2009 10 frances 3 eso - musee d orsayFrancesperillan
 
Libro+Mujeres+Y+Tercer+Sector
Libro+Mujeres+Y+Tercer+SectorLibro+Mujeres+Y+Tercer+Sector
Libro+Mujeres+Y+Tercer+Sectorguestfc2c7
 
L industrie du numerique en 2020 par G+9
L industrie du numerique en 2020 par G+9L industrie du numerique en 2020 par G+9
L industrie du numerique en 2020 par G+9Vincent DEMULIERE
 
[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...
[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...
[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...AT Internet
 
[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...
[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...
[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...AT Internet
 
PUBLICIDAD.Ppt
PUBLICIDAD.PptPUBLICIDAD.Ppt
PUBLICIDAD.Pptdiezmarzo
 
Voeux Humour
Voeux HumourVoeux Humour
Voeux HumourSycha
 
Informe anual 2011 Situación de la Libertad de Expresión en Venezuela
Informe anual 2011 Situación de la Libertad de Expresión en VenezuelaInforme anual 2011 Situación de la Libertad de Expresión en Venezuela
Informe anual 2011 Situación de la Libertad de Expresión en VenezuelaEspacio Público
 
Microsoft Advertising - Creative Solutions
Microsoft Advertising - Creative SolutionsMicrosoft Advertising - Creative Solutions
Microsoft Advertising - Creative SolutionsCharly Maltagliatti
 
Selfportraits
SelfportraitsSelfportraits
Selfportraitsnuriangf
 
Web academy special bien être 31 mai 2012 aix les bains
Web academy special bien être   31 mai 2012 aix les bainsWeb academy special bien être   31 mai 2012 aix les bains
Web academy special bien être 31 mai 2012 aix les bainsAlcimia
 
Mon Assurance Est Formidable
Mon Assurance Est FormidableMon Assurance Est Formidable
Mon Assurance Est Formidableguest2be3f8
 
Webinar Cómo optimizar sus emails en móviles
Webinar Cómo optimizar sus emails en móviles Webinar Cómo optimizar sus emails en móviles
Webinar Cómo optimizar sus emails en móviles MasterBase®
 
Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...
Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...
Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...Abel4com
 

Andere mochten auch (20)

Diaporama nture 2
Diaporama nture 2Diaporama nture 2
Diaporama nture 2
 
Carnet De Bord PôLe Technique
Carnet De Bord PôLe TechniqueCarnet De Bord PôLe Technique
Carnet De Bord PôLe Technique
 
Restful, really ? MixIt 2014
Restful, really ? MixIt 2014Restful, really ? MixIt 2014
Restful, really ? MixIt 2014
 
Ies isabel perillan 2009 10 frances 3 eso - musee d orsay
Ies isabel perillan 2009 10 frances 3 eso - musee d orsayIes isabel perillan 2009 10 frances 3 eso - musee d orsay
Ies isabel perillan 2009 10 frances 3 eso - musee d orsay
 
Libro+Mujeres+Y+Tercer+Sector
Libro+Mujeres+Y+Tercer+SectorLibro+Mujeres+Y+Tercer+Sector
Libro+Mujeres+Y+Tercer+Sector
 
L industrie du numerique en 2020 par G+9
L industrie du numerique en 2020 par G+9L industrie du numerique en 2020 par G+9
L industrie du numerique en 2020 par G+9
 
[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...
[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...
[Webinar] Audience Analytics : enrichissez vos analyses grâce aux profils qua...
 
[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...
[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...
[Case study] meinestadt.de développe la culture de la donnée dans l’entrepris...
 
Arman
ArmanArman
Arman
 
PUBLICIDAD.Ppt
PUBLICIDAD.PptPUBLICIDAD.Ppt
PUBLICIDAD.Ppt
 
Voeux Humour
Voeux HumourVoeux Humour
Voeux Humour
 
Informe anual 2011 Situación de la Libertad de Expresión en Venezuela
Informe anual 2011 Situación de la Libertad de Expresión en VenezuelaInforme anual 2011 Situación de la Libertad de Expresión en Venezuela
Informe anual 2011 Situación de la Libertad de Expresión en Venezuela
 
Microsoft Advertising - Creative Solutions
Microsoft Advertising - Creative SolutionsMicrosoft Advertising - Creative Solutions
Microsoft Advertising - Creative Solutions
 
Pampanitogrupo1
Pampanitogrupo1Pampanitogrupo1
Pampanitogrupo1
 
Selfportraits
SelfportraitsSelfportraits
Selfportraits
 
Web academy special bien être 31 mai 2012 aix les bains
Web academy special bien être   31 mai 2012 aix les bainsWeb academy special bien être   31 mai 2012 aix les bains
Web academy special bien être 31 mai 2012 aix les bains
 
Mon Assurance Est Formidable
Mon Assurance Est FormidableMon Assurance Est Formidable
Mon Assurance Est Formidable
 
Webinar Cómo optimizar sus emails en móviles
Webinar Cómo optimizar sus emails en móviles Webinar Cómo optimizar sus emails en móviles
Webinar Cómo optimizar sus emails en móviles
 
Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...
Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...
Le VE « éternellement émergent » est-il en train d’émerger? Institut de la Mo...
 
M6 es
M6 esM6 es
M6 es
 

Ähnlich wie Cours Transactions distribuées

Transaction.pptx
Transaction.pptxTransaction.pptx
Transaction.pptxSamirAwad14
 
Bibliothèque distribuée
Bibliothèque distribuéeBibliothèque distribuée
Bibliothèque distribuéeJulien
 
3 vb reference
3 vb reference3 vb reference
3 vb referencekkatia31
 
Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)
Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)
Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)Nabil Bouzerna
 
DVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptx
DVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptxDVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptx
DVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptxSedesiasGuillaume
 

Ähnlich wie Cours Transactions distribuées (8)

Transaction.pptx
Transaction.pptxTransaction.pptx
Transaction.pptx
 
Transaction.pdf
Transaction.pdfTransaction.pdf
Transaction.pdf
 
Bibliothèque distribuée
Bibliothèque distribuéeBibliothèque distribuée
Bibliothèque distribuée
 
Sécurité des bd
Sécurité des bd Sécurité des bd
Sécurité des bd
 
3 vb reference
3 vb reference3 vb reference
3 vb reference
 
Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)
Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)
Bitcoin: A Peer-to-Peer Electronic Cash System (traduction fr)
 
DVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptx
DVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptxDVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptx
DVGU Blockchain peer to peer mai 2018 Paris Dauphine.pptx
 
Réseaux partie 2.ppt
Réseaux partie 2.pptRéseaux partie 2.ppt
Réseaux partie 2.ppt
 

Cours Transactions distribuées

  • 1. @ Vincent Englebert - UNamur 1 Transactions & Concurrence version 2.0 Transactions & Concurrence version 2.0 1.1. TransactionTransaction 2.2. Gestion de la concurrenceGestion de la concurrence 3.3. Gestion de la concurrence entre transactionsGestion de la concurrence entre transactions (sérialisation des transactions)(sérialisation des transactions) 4.4. Protocole Two Phase CommitProtocole Two Phase Commit 5.5. Transactions imbriquéesTransactions imbriquées 6.6. Modèle X/OPENModèle X/OPEN 7.7. Transactions & CORBATransactions & CORBA 8.8. Exemple: transfert bancaire & CORBAExemple: transfert bancaire & CORBA
  • 2. Conditions Ces matériaux pédagogiques devenus obsolètes dans notre cursus sont distribués en l’état et ne sont plus maintenus. Tout emprunt vers d’autres supports respectera les conditions de la licence Creative Commons Attribution telle que déclarée dans l’entête en référençant: Source: Université de Namur Belgique – Faculté d’informatique – V. Englebert Si jamais, une information était incorrectement référencée dans ce document, les ayants-droits sont priés de me contacter afin de corriger le document: vincent.englebert (at) unamur.be @ Vincent Englebert – Unamur 2
  • 3. @ Vincent Englebert - UNamur 3 Transaction Transaction = Séquence d’instructions exécutées. Idéalement, une transaction est une opération (au sens macro) qui opère une transition valide dans l'espace des états autorisés du système. Les propriétés ACID Atomic Une transaction s’effectue complétement ou pas du tout Consistent Une transaction préserve l’intégrité de la base de données Isolated Une transaction ne doit pas se soucier de l’existence d’autres transactions. Durable L’effet d’une transaction doit être permanent. i1 i2 i3 i4 i5
  • 4. @ Vincent Englebert - UNamur 4 Atomic Si une transaction effectue un versement d’un compte à un autre, elle ne peut s’opérer à moitié Dupont.compte=Dupont.compte-100$ Martin.compte=Martin.compte+100$ Si un système garantit la propriété AACID, et si un crash (soft/hard) survient au milieu d’une transaction, le système nous garantit que l’état de la base de données sera restaurée comme si la transaction n’avait jamais été initiée. begin abort commit Transaction
  • 5. @ Vincent Englebert - UNamur 5 Limites de l’atomicité Begin-transaction IF compte >10.000$ THEN BEGIN print(« RETRAIT AUTORISÉ »); compte:=compte - 2.000$ END End-transaction Le problème se pose avec toutes les opérations qui ne sont pas « recoverable » impression hardware distributeur, lecteur de cartes, tapis roulant, moteur, … communication comment annuler un envoi de mail ?
  • 6. @ Vincent Englebert - UNamur 6 Consistency Vérifier que les contraintes d’intégrité sont vérifiées et que la base de données représente des états valides. Primary key Contraintes référentielles User constraint décédé ⇒ date_décés is not null select total_des_commandes from client where ncli=$1 = select sum(prixunitaire*quantité) from detail, produit, commande where detail.npro=produit.npro and detail.com=commande.ncom and commande.ncli=$1
  • 7. @ Vincent Englebert - UNamur 7 Isolation Soient T1=[a1 1 ,…,a1 n ] et T2=[a2 1 ,…,a2 m ] deux transactions composées d’actions. Une exécution des actions de T1 et T2 est sérialisable si elle produit les mêmes effets que l’exécution de T1 et T2 en série c-à-d: il existe une combinaison (ici: T1;T2 ou T2; T1) dont l'exécution produit les mêmes résultats et mêmes effets que l'ordonnancement proposé. Exemple: T(X) ≡ IF (X.compte > retrait ) THEN X.compte:=X.compte-retrait une exécution des transactions T(dupont) et T(dupont) où l’on testerait en même temps le montant du compte n’est pas sérialisable, puisque si on exécute ces transactions les unes après les autres, la seconde pourrait échouer ! Compte=1000 & retrait=700 Le respect de cette propriété nous garantit que si le système (DB, scheduler, …) exécute des transactions en parallèle, cela aura les mêmes caractéristiques qu’en série. Le programmeur n’a pas à tenir compte du contexte dans lequel va s’exécuter la transaction. Les modifications opérées durant une transaction ne sont pas visibles en dehors de cette dernière.
  • 8. @ Vincent Englebert - UNamur 8 Le problème du lost-update Trois comptes A,B,C avec 100, 200 et 300 dollars. On exécute deux transactions matérialisant deux transferts: transfert de 4$ de A vers B et transfert de 3$ de C vers B. L'exécution en parallèle de ces deux transactions peut amener à des inconsistences, si l'on ordonne mal les opérations qui les constituent. Transaction 1 balance1 A B C balance2 Transaction 2 ? 100$ 200$ 300$ ? balance1:=A 100$ A:=balance1-4 96$ balance2:=C 300$ C:=balance2-3 297$ balance1:=B 200$ balance2:=B 200$ B:=balance2+3 203$ B:=balance1+4 204$ 96$ 204$ 297$ lost-update
  • 9. @ Vincent Englebert - UNamur 9 Problème de la lecture erronée Une première transaction effectue un transfert d'argent entre deux compte alors qu'une autre calcule la somme des comptes. Transaction 1 balance1 A B C balance2 Transaction 2 ? 100$ 200$ 300$ ? balance1:=A 100$ A:=balance1-100 0$ balance2:=A; balance2:=balance2+B balance2:=balance2+C 500$ balance1:=B 200$ B:=balance1+100 300$ 0$ 300$ 300$ 500$
  • 10. @ Vincent Englebert - UNamur 10 Exécution sérialisée Il est néanmoins possible de trouver un plan d'exécution parallèle (ou interleaving) qui présente les mêmes caractéristiques qu'une exécution en série des deux transactions. Transaction 1 balance1 A B C balance2 Transaction 2 ? 100$ 200$ 300$ ? balance1:=A A:=balance1-4 100$ 96$ balance2:=C C:=balance2-3 297$ 300$ balance1:=B; B:=balance1+4 200$ 204$ balance2:=B B:=balance2+3 207$ 204$ 96$ 207$ 297$
  • 11. @ Vincent Englebert - UNamur 11 Durabilité Si des opérations doivent mettre à jour des données persistantes, leur mise à jour doit être effective. Exemple: le système doit être capable de prendre en compte tout problème qui surviendrait lors de l’enregistrement d’une information.
  • 12. @ Vincent Englebert - UNamur 12 Gestion de la concurrence Le mécanisme le plus répandu pour garantir qu’une exécution de transactions est sérialisable est la pose de verrous (lock). Principes chaque transaction réserve les ressources qu’elle utilise en posant un verrou dessus ligne de table SQL  fichier  disque  propriété; On distingue des verrous en écriture et en lecture (il peut y en avoir plus) Une transaction doit poser un verrou en lecture (resp. en écriture) sur une ressource avant de la lire (resp. écrire). La pose d’un verrou réussit ou échoue selon le tableau suivant: Lecture Écriture Lecture succès échec Écriture échec échec La pose d'un verrou avant d’accéder à une ressource ne garantitLa pose d'un verrou avant d’accéder à une ressource ne garantit néanmoins pas la sérialisation des transactions !néanmoins pas la sérialisation des transactions !
  • 13. @ Vincent Englebert - UNamur 13 Soient deux transactions T1 et T2 qui accèdent à deux ressources X et Y. T1 ≡ [ W ← X ; Y ← 1 ] T2 ≡ [ Z ← Y; X ← 2 ] Alors que chaque opération a obtenu le verrou correspondant, l’exécution proposée à gauche ne correspond à aucune sérialisation possible des deux transactions proposées. X Yr w rw W ← X Z ← Y X ← 2 Y ← 1 T1 T2 X Yr w rw X Yr w rw X Yr w rw X Yr w rw X Yr w rw T1;T2 T2;T1 E X 2 2 2 Y 1 1 1 W X0 2 X0 Z 1 Y0 Y0 Le fait que T1 aie relaché le verrou en lecture sur X a permis à T2 de modifier la valeur de X. X a donc une valeur « aléatoire » dans T1. OR cette valeur est en contradiction avec les exécutions sérielles.
  • 14. @ Vincent Englebert - UNamur 14 Le two-phase locking Une transaction procède en deux phases Phase 1: prendre des verrous sans en relacher Phase 2: relacher des verrous sans en prendre Nombredeverrousdétenus t Examinez le comportement de l’exemple précédent en utilisant le 2-phase locking. GOOD BAD
  • 15. @ Vincent Englebert - UNamur 15 Le gestionnaire de verrous Opérations Lock(transaction id, ressource id, mode de verrou) obtient si possible un verrou sur la ressource et sinon suspend l’exécution. Unlock(transaction id, ressource id) enlève le verrou préalablement posé par cette même transaction Unlock(transaction id) enlève tous les verrous d’une transaction (au commit par exemple). Ressources Verrous posés en attente x [T1,R] [T2,R] [T3,W] y [T2,W] [T4,R],[T1,R] z [T1,R] Problèmes ces opérations doivent être synchronisées ! Ces opérations sont invoquées pour chaque accès aux ressources Risque d’embouteillage  bottleneck ~ 100 instructions machine !!!
  • 16. @ Vincent Englebert - UNamur 16 Granularité Plus la portée du verrou sera petite Moins il y aura de conflits entre les transactions Cela augmente le nombre de transactions qui peuvent s’exécuter simultanément Plus le gestionnaire de verrous sera sollicité Sa structure de données augmente, + d’appels, + de conflits entre les appels (cfr. synchronized) Système Base de données TableLigne champ Exemples SQL: la portée du verrou est généralement la page. plusieurs lignes bloquées pour 1!1! ligne SGBD-OO: la portée du verrou est parfois l’objet. Granularité adaptive: le gestionnaire adapte la granularité en fonction du comportement de la transaction.
  • 17. @ Vincent Englebert - UNamur 17 Deadlock Un deadlock survient lorsque une transaction T1 nécessite une ressource verrouillée par une autre transaction T2 et réciproquement. Ressource Verrous en attente x [T1,R] [T2,W] y [T2,R] [T1,W] Il suffirait que l’une des transactions relache un verrou pour débloquer la situation, mais c’est contraire au principe du 2-Phase Locking. 2 Solutions Prévention des deadlocks (OS) Réduction des deadlocks (TP moniteur) Timeout-based detection Graph-based detection
  • 18. @ Vincent Englebert - UNamur 18 Timeout-based detection Si les transactions durent moins de 15 secs, et qu’une transaction est bloquée depuis Q secs (Q>15), alors faire un abort de cette transaction. Très simple à mettre en œuvre ne détecte un deadlock qu’après 15 secs, alors que le deadlock a pu apparaître à la première seconde: 14 secs perdues. Peut interrompre une transaction qui n’est pas dans un deadlock. Un transaction longue peut avoir du mal de résister à cette technique.
  • 19. @ Vincent Englebert - UNamur 19 Graph-based detection Représenter les dépendances entre transactions dans un graphe et analyser ce graphe de temps en temps. T1 T2 T7 T9 T6 T3 T4 T8 T5 " a besoin d’un verrou posé par " Exemple Tant qu’il existe un cycle, interrompre la transaction qui bloque le plus d’autres transactions ici T7 bloqueT9, T6, T3, T2, T1
  • 20. @ Vincent Englebert - UNamur 20 Deadlocks distribués From: Martin To: Peggy Qtt: 100 From: Peggy To: Martin Qtt: 200 Begin-Transaction If (from.solde>=Qtt) { from.debit(Qtt); to.credit(Qtt); } End-transaction T1,R,Martin T1,W,Martin T1,W,Peggy T2,R,Peggy T2,W,Peggy T2,W,Martin T2 T1 T2 T1 Martin Peggy
  • 21. @ Vincent Englebert - UNamur 21 Performances 1% deadlock : pose peu de problèmes Observations: K: nombre de demandes d’écriture par transaction D: nombre de ressources verrouillables N: nombre de transactions simultanées D NK 2 )conflitP( = 2 4 )deadlockP( D NK = Source:Bernstein97/p207
  • 22. @ Vincent Englebert - UNamur 22 Lock conversion une transaction demande un verrou en lecture et demande ensuite de commuter ce verrou en verrou en écriture. Si deux transactions mettent à jour une même donnée en même temps, cela aboutit à un deadlock, alors que si elles avaient demandé dès le départ un verrou en écriture, il y aurait juste eu exclusion mutuelle, blocage, mais pas de deadlock. SQL update CUSTOMER set AGE=36 where NAME=« MARTIN » ; L’analyseur SQL peut demander un verrou en écriture préventivement au vu de cette requête. Plus difficile avec une BD OO et Java par exemple.
  • 23. @ Vincent Englebert - UNamur 23 Arsenal augmenter le nombre de verrous, i.e., diminuer la granularité pour une table, faire un partitionnement vertical D NK 2 )conflitP( =2 4 )deadlockP( D NK = Produit code nom description taille prix en-stock seuil-commande abimés id: code 1-1 1-1Pro_Pro Produit en-stock seuil-commande abimés Produit code nom description taille prix id:code Produit_stock code en-stock seuil-commande abimés id: code equ Produit code nom description taille prix id: code On augmente D ! Essentiellement lecture de produit pour générer le catalogue on-line Mises-à-jour concentrées sur Produit_stock. Sans interférence avec Produit.
  • 24. @ Vincent Englebert - UNamur 24 Techniques d’optimisation Écourter au maximum la durée de vie des verrous Postposer les opérations juste avant la conclusion de la transaction Begin-transaction for cli in file_clients do { if read(cli.solde)>100.000 then write(cli.credit,true) else write(cli.credit,false); } End-transaction read(line 4125.solde) write(line 4125.credit,true) read(line 9547.solde) write(line 9547.credit,false) read(4125.solde) write(4125.credit,true) read(9547.solde) write(9547.credit,false) 256.325 26.782 Read only Replay and write iff success Read and write
  • 25. @ Vincent Englebert - UNamur 25 Degree isolation 2 / cursor stability Affaiblir les exigences d’une transaction dans l’aide à la décision, de nombreuses requêtes calculent des ratios, des indices, des sommes, … Pour ces requêtes, l’idée est de poser un verrou en lecture juste pendant la lecture de chaque donnée et de le relâcher après. Begin-transaction-molle Somme:=0 For cli in file-clients do { lock(cli.solde,read); X:=read(cli.solde); unlock(cli.solde); Somme:=Somme+X; } End-transaction-molle Begin-transaction write(6000.solde,66€) write(6002.solde,44€) End-transaction Les transactions sont encore sérialisables, mais ces queries ne peuvent garantir l’exactitude du résultat. Certains utilisateurs s’en accommodent néanmoins. viole le principe du 2P locking Exécution de cette transaction en plein milieu de l ’autre. Entre deux itérations, cette « transacti on » ne possède aucun verrou.
  • 26. @ Vincent Englebert - UNamur 26 Degree isolation 1 / dirty reads Aucun lock durant la lecture d’une information. On peut dont lire des données qui ne devraient pas exister! Exemple Begin-transactionBegin-transaction /* lock(cli,écriture) */ write(cli.national,keyboard()) while not isletter(read(cli.national)) do{ write(cli.national,keyboard()); } /* unlock(cli) */ End-transactionEnd-transaction Print(read(cli.nom)); Print(read(cli.national)); cette "transaction" travaille en ignorant la valeur des locks des ressources qu'elle utilise « Durant » « # » affiche
  • 27. @ Vincent Englebert - UNamur 27 Intention lock / intention de verrouillage Un intention lock est un pseudo-verrou que l’on pose sur une ressource composite afin de marquer l’intention de verrouiller un composant de ce dernier. Intention Lecture Lecture Intention Écriture Écriture Intention Lecture + + + - Lecture + + - - Intention Écriture + - + - Écriture - - - - On pose un « intentional lock » sur une ressource composite lorsqu'une transaction souhaite déposer un lock sur un de ses composants. Le fait de raisonner sur des locks « agrégés » évite de fastidieuses vérifications sur des locks indivuels.
  • 28. @ Vincent Englebert - UNamur 28 Banque NamurTournai Dupont Martin #125 #126 #127 #124 #123 T1: somme des avoirs de Monsieur Duchemin T2: transfert entre dupont et martin: #123→#126 T3: listing des clients de Tournai IR R IW IW W W IR Comparer cette configuration avec un modèle sans « intention locks ». Duchemin #128 #129 IW IR IW R exclusionexclusion T1 et T3 peuvent s'exécuter en concurrence. Test de deux locks uniquement! Il y a exclusion entre T2 et T3  T1 et T2 peuvent s'exécuter en concurrence si les comptes sont disjoints (c'est le cas ici).  Coût: gérer les locks sur la hauteur d'une arborescence.
  • 29. @ Vincent Englebert - UNamur 29 Gestion de la concurrence entre transactions La gestion de la concurrence avec des verrous pose certains problèmes: La gestion des verrous constitue un overhead non négligeable, même lorsque les transactions ne se menacent pas entre elles. L'utilisation de verrous provoque des deadlocks qu'il faut gérer soit par détection soit avec une technique de timeout. Puisque les verrous ne peuvent être relâchés avant la fin de la transaction, cela réduit les possibilités d'exécutions concurrentes. Usage parfois trop pessimiste des verrous Begin-transaction lock(x,y); if (condition) x:=1 else y:=1 unlock(x,y); end-transaction Dans les faits, les conflits sont assez rares Déplacer la gestion du problème lorsqu'il y a conflit uniquement. On laisse s'exécuter les transactions (sans poser de verrous!) et on examine le risque de conflit à la fin, avant de conclure la transaction. Begin-transaction assert x==1 x:=1 end-transaction
  • 30. @ Vincent Englebert - UNamur 30 Sérialisation des transactions Cfr. Slides LaTeX (sérialisation des transactions)
  • 31. @ Vincent Englebert - UNamur 31 Le Protocole Two-Phase Commit Lorsqu’une transaction concerne plusieurs gestionnaires de ressources, comment synchroniser ceux-ci pour que tous exécutent la transaction ou aucun ? Un gestionnaire de ressources peut tomber en panne le coordinateur peut tomber en panne Le réseau de communication peut être défectueux Gestionnaire Ressources Gestionnaire Ressources Gestionnaire Ressources Gestionnaire Ressources Gestionnaire Ressources Gestionnaire Ressources CoordinateurCoordinateur
  • 32. @ Vincent Englebert - UNamur 32 HypothèsesHypothèses Une transaction provoque un abort si elle rencontre un problème, et provoque un commit sinon. Cela mettra en œuvre le protocole 2PC . Chaque gestionnaire de ressources peut faire un commit ou un abort de la partie de la transaction qui le concerne. Un seul programme ordonne l’ordre commit. Si plusieurs ordres commit étaient lancés durant le 2PC, un gestionnaire pourrait faire un commit alors qu’un autre ferait un abort. Nous sommes dans un environnement distribué, plusieurs programmes peuvent être impliqués dans la transaction et donc lancer indépendamment l'ordre commit ou abort. Lorsque l’ordre commit est lancé, les opérations impliquées dans la transaction doivent être terminées sur tous les gestionnaires. Tâche exécutée de manière synchrone: pas de problème Tâche exécutée de manière asynchrone: travail supplémentaire pour s’assurer de la fin de l’exécution. Exemple: module { onewayoneway void do_something(); … } begin_transaction(); object_remote.do_something(); commit(); Le système n’a pas de comportement frauduleux, il fait ce qu’il dit qu’il fait. Les composants utilisent un timeout pour décider qu’un autre composant est en panne ou que le réseau est défectueux . Les serveurs et réseaux fonctionnent dfe temps en temps, au moins !
  • 33. @ Vincent Englebert - UNamur 33 Les deux phasesLes deux phases Phase 1 s’assurer que chaque gestionnaire est prêt à faire un commit. Exemple: toutes les informations pour mettre à jour la BD sont disponibles et stockées en lieu sûr. Si le gestionnaire tombe en panne alors qu’il a dit qu’il était prêt, il s’engage à avoir assez d’informations pour retrouver l’état d’avant la panne. Phase 2 le coordinateur initie le commit sur chaque gestionnaire Coordinateur Gestionnaire Gestionnaire Gestionnaire request-to-prepare prepared commit done DONE: la requête a été reçue DONE: la requête a été reçue
  • 34. @ Vincent Englebert - UNamur 34 Coordinateur Gestionnaire Gestionnaire Gestionnaire request-to-prepare prepared abort done prepared no
  • 35. @ Vincent Englebert - UNamur 35 Les moments entre lesquels un gestionnaire émet le message « prepared » et reçoit la requête « abort » ou « commit » est appelée « période d’incertitude ». Le gestionnaire ne peut prendre aucune initiative durant cette période. Si le coordinateur ou le réseau a une défaillance, le gestionnaire est bloqué. Les acteurs (gestionnaires & coordinateur) utilisent un système de log fiable. Le demande d'écriture rend la main lorsque l'information est écrite définitivement. ThéorèmeThéorème Pour tout protocole de commit distribué (et pas seulement ceux à deux-phases), une défaillance de communication peut laisser un gestionnaire dans un état bloqué.
  • 36. @ Vincent Englebert - UNamur 36 Gestion des échecs de transmissionGestion des échecs de transmission Point de vue du coordinateurcoordinateur émission du message « request-to-prepare » on envoie une bouteille à l’eau, rien de grave ne peut se passer réception des messages « prepared » et/ou « no » si l’un des gestionnaires ne répond pas endéans le timeout, on considère qu’il a envoyé le message « no ». Si un ou plusieurs messages « no » sont reçus, alors le coordinateur provoque un abort. Émission du message « commit » ou « abort » . on envoie une bouteille à l’eau, rien de grave ne peut se passer Réception du message « done » des gestionnaires si un message n’est pas reçu, alors attendre plus longtemps ou réveiller le gestionnaire en renvoyant le dernier message (commit ou abort)
  • 37. @ Vincent Englebert - UNamur 37 Du point de vue du gestionnairegestionnaire Réception du message « request-to-prepare » après voir fait le job requis par la transaction, si le gestionnaire ne reçoit pas ce message endéans le timeout, il décide d’avorter la transaction. Il restera silencieux, ce qui revient au même qu’un message « no ». Émettre un message « prepared » ou « no » selon que la préparation s’est bien passée ou non. ⇒ Pas de problèmes. Réception du « commit » ou « abort » on est dans la période d’incertudepériode d’incertude. Le gestionnaire ne peut prendre aucune initiative. Émettre le message « done ». ⇒ Pas de problèmes.
  • 38. @ Vincent Englebert - UNamur 38 Gestion des crashesGestion des crashes Écrire la liste des gestionnaires participant à la transaction dans le Log. Écrire le mot commit/abort dans le Log. Écrire le mot done dans le log. Aucun message n'a été envoyé aux gestionnaires. Aucun gestionnaire n’a reçu le message commit. Un no a été reçu ou un prepared n'a pas été reçu endéans le timeout. Le coordinateur décide d’avorter la transaction. De leur côté, certains gestionnaires ont peut-être déjà avorté la transaction. Si on ne reçoit pas le message done endéans le timeout, on réémet le message du log-file. Attente éventuellement infinie. Tout a été fait dans les règles. Il n’y a rien à faire, la transaction est clôturée. GestionnaireGestionnaireCoordinateur Gestionnaire request-to-prepare prepared|no Commit|abort done log(start;G1,G2,…,Gn) log(commit/abort) log(done) 1. 2. 3. 4. log(prepared|no) log(committed/aborted) A. B. C.
  • 39. @ Vincent Englebert - UNamur 39 Gestion Crash Coordinateur CRASH PHASE 1 Rien n'a été entrepris. Pas de problème donc. CRASH PHASE 2 Quand le coordinateur est "réanimé", il trouve le mot "start" et la liste des gestionnaires dans le log file. Si le gestionnaire avait commencé à recevoir des messages des gestionnaires, ils sont perdus. Réémettre le message "request-to-prepare" aux gestionnaires. CRASH PHASE 3 Renvoyer le message trouvé dans le log file ("commit" ou "abort") CRASH PHASE 4 Si le coordinateur trouve le mot "done" dans le log file, il peut se reposer.
  • 40. @ Vincent Englebert - UNamur 40 Écrire le mot prepared dans le Log quand toutes les informations nécessaire à un recovery ont été préservées et que l’on a reçu le message request-to-prepare Écrire le mot committed ou aborted dans le log. A On ne reçoit pas de request-to-prepare endéans le timeout après avoir préparé la transaction locale. Le gestionnaire peut décider d'avorter. Il suffira ne pas envoyer le message prepared ou de répondre no à la l'éventuelle prochain message request-to-prepare. B L’information pour faire un recovery est disponible: le gestionnaire peut faire un commit s'il reçoit un commit faire un abort s'il reçoit un abort n’avoir rien reçu (période d'incertitude)(période d'incertitude)  Essayer de rétablir la communication avec le coordinateur, intervention manuelle, … C On n'attend aucun message, il suffit de terminer la transaction locale (confiée au SGBD par exemple) et de renvoyer done.  pas de problèmes donc. GestionnaireGestionnaireCoordinateur Gestionnaire request-to-prepare prepared | no Commit|abort done log(start) log(commit | abort) log(done) 1. 2. 3. 4. log(prepared|no) log(committed | aborted) A. B. C.
  • 41. @ Vincent Englebert - UNamur 41 Gestion Crash Gestionnaire CRASH PHASE A Le gestionnaire trouve le log file vide: les informations à propos de la transaction n'ont peut-être pas pu être mis en lieu sûr: il décide de se saborder: répondre no au prochain "request-to-prepare" ou ne pas répondre. CRASH PHASE B Les informations sur la transaction locale sont en lieu sûr. Le gestionnaire attend l'ordre "commit"  ou "abort" du coordinateur. (il l'avait peut-être déjà reçu et donc perdu…). période d'incertitude CRASH PHASE C Renvoyer le message "done" au coordinateur.
  • 42. @ Vincent Englebert - UNamur 42 Transactions imbriquées Une transaction imbriquée est un arbre de transactions qui sont elles- mêmes imbriquées ou simples. Les transactions aux feuilles de l'arbre sont des transactions simples Une transaction fille peut faire soit un commit ou un abort. Le commit n'a d'effet que si le parent fait aussi un commit (et ainsi de suite). En attendant, les résultats du commit ne sont visibles que des transactions parentes (directes ou indirectes) un abort (i.e. rollback) entraîne l'annulation de toutes les transactions filles de celle-ci (qu'elles aient fait un commit ou pas!). ACID : les transactions imbriquées dans d'autres transactions ne sont pas durables! Mais la racine l'est! Les objets détenus par une transaction mère sont accessibles aux transactions filles. Si deux transactions filles s'exécutent en parallèle, les effets de l'une ne sont pas visibles de l'autre et récipr. : Isolation
  • 43. @ Vincent Englebert - UNamur 43 T1,1 T1,2 T1,1,1 T1,1,2 T1 T1,2,2 begin transaction commit 1←x 1=x 0=x0=x 1=x Roll-back
  • 44. @ Vincent Englebert - UNamur 44 T1,1 T1,2 T1,1,1 T1,1,2 T1 T1,2,2 begin transaction 1←x 1=x 0=x0=x 0=x Roll-back
  • 45. @ Vincent Englebert - UNamur 45 @ MSDN Nested Transactions A nested transaction occurs when a new transaction is started on a session that is already inside the scope of an existing transaction. The new, nested transaction is said to be nested within (or below the level of) the existing transaction. Changes made within the nested transaction are invisible to the top-level transaction until the nested transaction is committed. Even then, the changes are not visible outside the top-level transaction until that transaction is committed. Providers that expose ITransactionLocal and support nested transactions can choose to support only a limited number of nested transactions, including zero. For providers that support nested transactions, calling ITransactionLocal::StartTransaction on a session with an existing transaction begins a new transaction nested below the current transaction. The return level indicates the level of nesting: a return value of 1 indicates a top-level transaction (that is, a transaction that is not nested within another transaction); 2 indicates a second-level transaction (a transaction nested within a top-level transaction); and so on. Each nested transaction is represented by a transaction object. Calling ITransaction::Commit or ITransaction::Abort on the session object commits or aborts the transaction at the current (lowest) nesting level. Calling Commit or Abort on a transaction object nested at a given level commits or aborts the transaction at that nesting level. Committing or aborting a transaction commits or aborts all transactions nested below it as well. Calling ITransaction::Commit or ITransaction::Abort on a transaction object with the fRetaining flag set to TRUE implicitly begins a new unit of work, and the transaction object remains valid. Calling Commit or Abort with fRetaining set to FALSE terminates the transaction, and the transaction object enters a zombie state. At this point, the only valid action that can be performed on the transaction object is to release it. Before the resources used by a transaction object can be freed by the provider, the transaction object and all transaction objects nested below it must be released. Releasing a transaction object aborts any uncommitted work performed in that transaction.
  • 46. @ Vincent Englebert - UNamur 46 @ENCINA from IBM Nested and top-level transactions As described in the previous section, a nested transaction is begun within the scope of another transaction. The transaction that starts the nested transaction is called the parent of the nested transaction. There are two types of nested transactions: • A nested top-level transaction commits or aborts independently of the enclosing transaction. That is, after it is created, it is completely independent of the transaction that created it. The Tran-C topLevel construct for creating nested top-level transactions. The syntax of this construct is identical to that of the transaction construct, but the topLevel keyword is used instead of the transaction keyword. • A nested subtransaction commits with respect to the parent transaction. That is, even though the subtransaction commits, the permanence of its effects depends on the parent transaction committing. If the parent transaction aborts, the results of the nested transaction are backed out. However, if the nested transaction aborts, the parent transaction is not aborted. The easiest way to create a nested subtransaction transaction in Tran-C is to simply use a transaction block within the scope of an existing transaction. Tran-C automatically makes the new transaction a subtransaction of the existing transaction. In this chapter, when we discuss nested transactions, we are generally referring to nested subtransactions unless we specify otherwise. A series of nested subtransactions is viewed as a hierarchy of transactions. When transactions are nested to an arbitrary depth, the transaction that is the parent of the entire tree (family) of transactions is referred to as the top-level transaction. If the top-level transaction aborts, all nested transactions are aborted as well. By default, nested subtransactions of the same parent transaction are executed sequentially within the scope of the parent. The Tran-C concurrent and cofor statements can be used to create subtransactions that execute concurrently with each other on behalf of their parent transaction. For more information, see the Encina Transactional Programming Guide.
  • 47. @ Vincent Englebert - UNamur 47 @ENCINA from IBM error_status_t OrderItem(idl_ulong_int stockNum, idl_ulong_int numOrdered, idl_ulong_int customerId) { idl_long_int returnStatus; idl_long_int costPerItem, totalCost; short priority; volatile short preferredCustomer = TRUE; transaction{ PlaceOrder(stockNum, numOrdered, &costPerItem); totalCost = numOrdered * costPerItem; if (totalCost > 1000) priority = HIGH_PRIORITY; else priority = NORMAL_PRIORITY; PlaceItemOnQueue(stockNum, numOrdered, customerId, priority); transaction{/* Begin a nested transaction. */           BillPreferredCustomer(customerId, totalCost); } onAbort { /* If nested transaction aborts. */ preferredCustomer = FALSE; } /* If nested transaction aborted, check mainframe database */ if (!preferredCustomer)      BillForItem(customerId, totalCost); }onCommit{ fprintf(stderr, "We committed.n"); return SUCCESS; }onAbort{ fprintf(stderr, "We aborted. %sn", abortReason()); return ORDER_FAILED; } }
  • 48. @ Vincent Englebert - UNamur 48 Le modèle X/OpenLe modèle X/Open X/Open a défini un ensemble de passerelles pour que des technologies hétérogènes puissent être utilisées dans des applications transactionnelles. TX: définit l'interface entre une application et le gestionnaire de transactions. Exemple tx_begin, tx_commit, tx_rollback, tx_open, tx_close, tx_info,tx_set_commit_return, tx_set_transaction_timeout XA: définit l'interface entre le coordinateur de transactions et le gestionnaire de ressources Programme d'applicationProgramme d'application Gestionnaire de ressources Gestionnaire de ressources Gestionnaire de ressources Gestionnaire de ressources Gestionnaire de ressources Gestionnaire de ressources Coordinateur de TransactionsCoordinateur de Transactions TX interface start, commit, abort XA interface 2PC operations SQL JDBC ODBC ISAM ...
  • 49. @ Vincent Englebert - UNamur 49 Exemple: XA-protocole
  • 50. @ Vincent Englebert - UNamur 50 Les Transactions et CORBA OTS (Object Transaction Service) OTS est une description en termes OO (i.e. IDL) de l'architecture décrite par l'X/Open. Transactions imbriquées Transactions distribuées Gestion des transactions implicites (ou non) Propagation des transactions contrôlées par le programmeur Portabilité (i.e. indépendance % technologie du TP moniteur) Support d'applications multi-thread (client & serveur) Performances similaires à l'X/Open procédural (en termes de messages émis sur le réseaux) Interopérabilité avec d'autres systèmes (X/Open)
  • 51. @ Vincent Englebert - UNamur 51
  • 52. @ Vincent Englebert - UNamur 52 Transaction dans un exemple 3-tiers Client Transactionnel Client Transactionnel Objet Transactionnel Objet Récupérable Serveur Transactionnel Serveur Récupérable Service de Transactions Contexte de Transaction begin commit roll-back roll-back register roll-back 2PC Protocole ClientClientClientClient BusinessBusinessBusinessBusiness RepositoryRepositoryRepositoryRepository RessourceRessource Ressource
  • 53. @ Vincent Englebert - UNamur 53
  • 54. @ Vincent Englebert - UNamur 54 Les concepts Client Transactionnel Programme pouvant invoquer des opérations sur des objets transactionnels dans une transaction. Objet Transactionnel Objet dont le comportement est affecté par le fait de participer à une transaction. Un objet peut assumer la transaction pour certaines requêtes et pas pour d'autres, ce comportement est dynamique. Objet Récupérable (recoverable) Objet dont les données sont affectées par l'issue (commit | rollback) d'une transaction. Un objet récupérable est un objet transactionnel. Un objet récupérable participe au protocole de gestion de la transaction en enregistrant un objet « ressource » auprès du service de transaction. Le service de transaction coordonne la transaction en dialoguant avec les ressources. Serveur Transactionnel Collection d'un ou plusieurs objets transactionnels (objets récupérables exclus). Ce serveur n'est pas impliqué par la clôture des transactions mais peut provoquer un rollback. Serveur Récupérable (recoverable) Collection d'objets transactionnels dont un au moins est récupérable. Il participe au protocole en enregistrant des ressources. Le service de transaction gère la transaction en dialoguant avec les ressources enregistrées.
  • 55. @ Vincent Englebert - UNamur 55 Types de transactions Le Service Transactions de CORBA fournit les interfaces pour gérer des transactions plates (requis) des transactions imbriquées (en option) Une transaction est clôturée par le client transactionnel qui est à son origine certaines implémentations peuvent déroger à cette règle N'importe quel composant intervenant dans une transaction peut provoquer un rollback. le composant a un problème impossible de faire le commit DB, disque en panne, manque de ressources, … conditions non satisfaites Sécurité Annulation de l'opérateur …
  • 56. @ Vincent Englebert - UNamur 56 InterfaceInterface ControlControl Représente le concept de transaction (simple ou imbriquée). Comme pour tout autre objet distribué, on utilise un factory pour créer un objet Control. Terminator get_terminator(…); Coordinator get_coordinator(); Interface TransactionFactoryInterface TransactionFactory Factory pour créer des objets de type Control. Control create(in unsigned long tiime_out) Interface TerminatorInterface Terminator void commit(…); void rollback(); Interface CoordinatorInterface Coordinator Fournit les opérations requises pour enregistrer les ressources impliquées par le protocole 2PC. RecoveryCoordinator register_ressource(in Resource) Interface ResourceInterface Resource Décrit le comportement d'un objet considéré comme une ressource pour le 2PC scénario. Exemple: gérer un fichier texte comme une ressource !!! Vote prepare();Vote prepare(); void rollback();void rollback(); void commit();void commit(); void commit_one_phase();void commit_one_phase(); void forget();void forget(); fr:ressource en:resource
  • 57. @ Vincent Englebert - UNamur 57 Interface CurrentInterface Current Associé à tout objet qui hérite de l'interface TransactionalObject. Représente la transaction courante durant l'invocation de l'opération. Sa valeur est gérée par le POA. Permet d’obtenir la référence du « Control ». Un current par thread. void begin();void begin(); void commit(in boolean report);void commit(in boolean report); void rollback();void rollback(); Control get_control();Control get_control();
  • 58. @ Vincent Englebert - UNamur 58 Programmation expliciteProgrammation explicite le programmeur doit gérer explicitement la transaction créer une transaction (Control) passer le Control comme paramètre de l'opération et ainsi de suite. R1 R3R2 O1O1 O2O2 O3O3Client C:Contro l O4O4 C C C Certaines méthodes peuvent être soumises à une transaction et d'autres pas Exemple Mise à jour de la base de données  oui [update_db(info,control)] Mise à jour du fichier d'audit trail  non [update_log(info)] l'instance qui initie la transaction ne doit pas nécessairement être celle qui la termine (abort/commit). Exemple (workflow) pas nécessairement supporté par tous les OTS. Saisie Mise-à-jourvérification Approuver & imprimer begin abort/commit abort/commit abort/commit
  • 59. @ Vincent Englebert - UNamur 59 Programmation impliciteProgrammation implicite tout type d'objet qui participe à une transaction doit hériter de CosTransactions::TransactionalObject. Cette interface est vide et constitue juste une astuce qui permettra à l'ORB de gérer les objets de ce type comme des objets transactionnels. L'ORB associe systématiquement un Control avec les méthodes de ces objets. CORBA fournit une pseudo-interface qui décrit un objet utilitaire pour faciliter la programmation des transactions. boolean commit=true; try { CosOTS::Current::begin(); […] compte.transfert(compte_to,10000); CosOTS::Current::commit(); } catch (CORBA::TRANSACTION_ROLLBACK){ cosOTS::Current::rollback(); System.out.println(« Rollback exception, opération avortée »); commit=false; } catch (...){ cosOTS::Current::rollback(); System.out.println(« exception bizarre!  rollback »); commit=false; } if (commit) { System.out.println(« opération réussie »); }
  • 60. @ Vincent Englebert - UNamur 60 module CosTransactions { enum Status { StatusActive, StatusMarkedRollback, StatusPrepared, StatusCommitted, StatusRolledBack, StatusUnknown, StatusNoTransaction, StatusPreparing, StatusCommitting, StatusRollingBack }; enum Vote { VoteCommit, VoteRollback, VoteReadOnly }; struct TransIdentity { Coordinator coord; Terminator term; otid_t otid; }; struct PropagationContext { unsigned long timeout; TransIdentity current; sequence <TransIdentity> parents; any implementation_specific_data; }; local interface Current : CORBA::Current { void begin() raises(SubtransactionsUnavailable); void commit(in boolean report_heuristics) raises(NoTransaction,HeuristicMixed,HeuristicHazard); void rollback() raises(NoTransaction); void rollback_only() raises(NoTransaction); Status get_status(); string get_transaction_name(); void set_timeout(in unsigned long seconds); Control get_control(); Control suspend(); void resume(in Control which) raises(InvalidControl); };
  • 61. @ Vincent Englebert - UNamur 61 interface TransactionFactory { Control create(in unsigned long time_out); Control recreate(in PropagationContext ctx); }; interface Control { Terminator get_terminator() raises(Unavailable); Coordinator get_coordinator() raises(Unavailable); }; interface Terminator { void commit(in boolean report_heuristics) raises(HeuristicMixed,HeuristicHazard); void rollback(); };
  • 62. @ Vincent Englebert - UNamur 62 interface Coordinator { Status get_status(); Status get_parent_status(); Status get_top_level_status(); boolean is_same_transaction(in Coordinator tc); boolean is_related_transaction(in Coordinator tc); boolean is_ancestor_transaction(in Coordinator tc); boolean is_descendant_transaction(in Coordinator tc); boolean is_top_level_transaction(); unsigned long hash_transaction(); unsigned long hash_top_level_tran(); RecoveryCoordinator register_resource(in Resource r) raises(Inactive); void register_synchronization (in Synchronization sync) raises(Inactive, SynchronizationUnavaila void register_subtran_aware(in SubtransactionAwareResource r) raises(Inactive, NotSubtransaction void rollback_only() raises(Inactive); string get_transaction_name(); Control create_subtransaction() raises(SubtransactionsUnavailable, Inactive); PropagationContext get_txcontext () raises(Unavailable); }; interface RecoveryCoordinator { Status replay_completion(in Resource r) raises(NotPrepared); }; interface Resource { Vote prepare() raises(HeuristicMixed,HeuristicHazard); void rollback() raises(HeuristicMixed,HeuristicHazard); void commit() raises(NotPrepared,HeuristicRollback,HeuristicMixed,HeuristicHazard); void commit_one_phase() raises(HeuristicHazard); void forget(); };
  • 63. @ Vincent Englebert - UNamur 63 interface TransactionalObject {}; interface Synchronization : TransactionalObject { void before_completion(); void after_completion(in CosTransactions::Status status); }; interface SubtransactionAwareResource : Resource { void commit_subtransaction(in Coordinator parent); void rollback_subtransaction(); }; };
  • 64. @ Vincent Englebert - UNamur 64 Vue d'ensemble du module OTS Terminator commit rollback Coordinator register_resource Resource vote prepare void rollback void commit Control coordinateur: *Coordinator terminateur: *Terminator Terminator get_terminator Coordintaor get_coordinator Current context: *Control void begin void commit void rollback Control get_control TransactionFactory Control create
  • 65. @ Vincent Englebert - UNamur 65 :CoordinatorFrom:account (Resource) To:Account (Resource) :CurrentClient:App.exe begin() debit(100) credit(100) get_control() register_resource() get_control() register_resource() commit() commit() commit() prepare() prepare()
  • 66. From:account :XADataStore To:Account :XADataStore :CoordinatorClient:App.exe Begin() Commit() Debit(100) Credit(100) Register_resource() Xa_start() Read/write() Xa_end() Register_resource() Xa_start() Read/write() Xa_end() Vote() Xa_start() Write modified data Xa_end Xa_prepare Xa_start() Write modified data Xa_end Xa_prepare Vote() doCommit() doCommit() Xa_commit() Xa_commit()
  • 67. @ Vincent Englebert - UNamur 67 Exemple: transfert bancaireExemple: transfert bancaire #include <CosTransactions.idl> module WithResource{ interface AccountResource : CosTransactions::Resource { float balance(); void credit( in float value ); void debit( in float value ); }; interface Account : CosTransactions::TransactionalObject{ float balance(); void credit( in float value ); void debit( in float value ); }; exception NotExistingAccount { }; interface Bank { Account create_account( in string name ); Account get_account( in string name ) raises( NotExistingAccount ); }; };
  • 68. @ Vincent Englebert - UNamur 68 class Client { void main(){ org.omg.CosTransactions.Current current = null; org.omg.CORBA.Object obj = _orb.resolve_initial_references("TransactionCurrent"); current = org.omg.CosTransactions.CurrentHelper.narrow( obj ); current.begin(); Account supplier = _bank.get_account( name_supplier ); Account consumer = _bank.get_account( name_consumer ); supplier.debit( famount ); consumer.credit( famount ); current.commit( false ); } } Le code de cette application a été nettoyé des instruction de traitement d'exception. On suppose que le client a déjà résolu les diverses références vers ses objets distants.
  • 69. @ Vincent Englebert - UNamur 69 package WithResource; public class BankServer { public static void main( String [] args ) { org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); org.omg.CORBA.Object objPoa = null; org.omg.PortableServer.POA rootPOA = null; objPoa = orb.resolve_initial_references("RootPOA"); rootPOA = org.omg.PortableServer.POAHelper.narrow(objPoa); BankImpl bank = new BankImpl( orb ); byte[] servantId=rootPOA.activate_object(bank); org.omg.CORBA.Object obj=rootPOA.id_to_reference(servantId); String reference = orb.object_to_string(obj); java.io.FileOutputStream file = new java.io.FileOutputStream("ObjectId"); java.io.PrintStream pfile=new java.io.PrintStream(file); pfile.println(reference); file.close(); rootPOA.the_POAManager().activate(); System.out.println("The bank server is now ready..."); orb.run(); } }
  • 70. @ Vincent Englebert - UNamur 70 package WithResource; public class BankImpl extends BankPOA { private java.util.Hashtable _accounts; private org.omg.CORBA.ORB _orb; public BankImpl( org.omg.CORBA.ORB orb ) { _accounts = new java.util.Hashtable(); _orb = orb; } public Account create_account( String name ) { AccountImpl acc = new AccountImpl( name ); _poa().activate_object(acc); _accounts.put( name, acc ); return acc._this( ); } public Account get_account( String name ) throws NotExistingAccount { AccountImpl acc = ( AccountImpl ) _accounts.get( name ); if ( acc == null ) { throw new NotExistingAccount(); } return acc._this(); } }
  • 71. @ Vincent Englebert - UNamur 71 package WithResource; public class AccountImpl extends AccountPOA { float _balance; private org.omg.CORBA.ORB _orb; java.util.Vector _resources; private String _name; public AccountImpl( org.omg.CORBA.ORB orb, String name ){ _balance = 0; _orb = orb; _resources = new java.util.Vector(); _name = name; } public float balance() { return get_resource().balance(); } public void credit( float value ) { get_resource().credit( value ); } public void debit( float value ) { get_resource().debit( value ); } public void rollbackOnly() { CORBA.Object obj = _orb.resolve_initial_references("TransactionCurrent"); CosTransactions.Current current = CosTransactions.CurrentHelper.narrow( obj ); current.rollback_only(); } à suivre ...
  • 72. @ Vincent Englebert - UNamur 72 ... public AccountResource get_resource() { org.omg.CORBA.Object objPoa = null; org.omg.PortableServer.POA rootPOA = null; CORBA.Object obj = _orb.resolve_initial_references("TransactionCurrent"); CosTransactions.Current current = CosTransactions.CurrentHelper.narrow( obj ); CosTransactions.Coordinator coordinator = current.get_control().get_coordinator(); AccountResourceImpl resource = null; for ( int i=0; i<_resources.size(); i++ ) { resource = ( AccountResourceImpl ) _resources.elementAt( i ); if ( coordinator.is_same_transaction( resource.coordinator() ) ) return resource._this( ); } System.out.println("Create a new resource for " + _name ); resource = new AccountResourceImpl( _poa(), coordinator, this, _name ); objPoa = _orb.resolve_initial_references("RootPOA"); rootPOA = org.omg.PortableServer.POAHelper.narrow(objPoa); rootPOA.activate(resource) AccountResource res = resource._this(); coordinator.register_resource( res ); _resources.addElement( resource ); return res; } }
  • 73. @ Vincent Englebert - UNamur 73 package WithResource; public class AccountResourceImpl extends AccountResourcePOA{ private float _initial_balance; private float _current_balance; private CosTransactions.Coordinator _coordinator; private AccountImpl _account; private String _name; private PortableServer.POA _poa; public AccountResourceImpl( PortableServer.POA poa, CosTransactions.Coordinator coordinator, AccountImpl account, String name ) { _coordinator = coordinator; _name = name; _poa = poa; _account = account; _initial_balance = account._balance; _current_balance = _initial_balance; } public float balance() { return _current_balance; } public void credit( float value ) { _current_balance += value; } public void debit( float value ) { _current_balance -= value; } à suivre ...
  • 74. @ Vincent Englebert - UNamur 74 ... public CosTransactions.Vote prepare() { System.out.println("[ Resource for " + _name + " : Prepare ]"); if ( _initial_balance == _current_balance ) { // No change removeItself(); return CosTransactions.Vote.VoteReadOnly; } if ( _current_balance < 0 ) { removeItself(); return CosTransactions.Vote.VoteRollback; } return CosTransactions.Vote.VoteCommit; } public void rollback() { System.out.println("[ Resource for " + _name + " : Rollback ]"); removeItself(); } public void commit() { System.out.println("[ Resource for " + _name + " : Commit ]"); _account._balance = _current_balance; removeItself(); } public void commit_one_phase() { System.out.println("[ Resource for " + _name + " : Commit one phase ]"); _account._balance = _current_balance; removeItself(); } à suivre ...
  • 75. @ Vincent Englebert - UNamur 75 public void forget() { System.out.println("[ Resource for " + _name + " : Forget ]"); removeItself(); } public CosTransactions.Coordinator coordinator() { return _coordinator; } private void removeItself() { _account._resources.removeElement( this ); _poa.deactivate_object( _poa.servant_to_id( this ) ); } }
  • 76. FIN