@ Vincent Englebert - UNamur 1
Transactions & Concurrence
version 2.0
Transactions & Concurrence
version 2.0
1.1. Transact...
Conditions
Ces matériaux pédagogiques devenus obsolètes dans notre cursus
sont distribués en l’état et ne sont plus mainte...
@ Vincent Englebert - UNamur 3
Transaction
Transaction
= Séquence d’instructions exécutées.
Idéalement, une transaction es...
@ Vincent Englebert - UNamur 4
Atomic
Si une transaction effectue un versement d’un compte à un autre, elle
ne peut s’opér...
@ Vincent Englebert - UNamur 5
Limites de l’atomicité
Begin-transaction
IF compte >10.000$
THEN BEGIN
print(« RETRAIT AUTO...
@ Vincent Englebert - UNamur 6
Consistency
Vérifier que les contraintes d’intégrité sont vérifiées et que la base de
donné...
@ Vincent Englebert - UNamur 7
Isolation
Soient T1=[a1
1
,…,a1
n
] et T2=[a2
1
,…,a2
m
] deux transactions composées d’act...
@ Vincent Englebert - UNamur 8
Le problème du lost-update
Trois comptes A,B,C avec 100, 200 et 300 dollars.
On exécute deu...
@ Vincent Englebert - UNamur 9
Problème de la lecture erronée
Une première transaction effectue un transfert d'argent entr...
@ Vincent Englebert - UNamur 10
Exécution sérialisée
Il est néanmoins possible de trouver un plan d'exécution parallèle (o...
@ Vincent Englebert - UNamur 11
Durabilité
Si des opérations doivent mettre à jour des données persistantes, leur
mise à j...
@ Vincent Englebert - UNamur 12
Gestion de la concurrence
Le mécanisme le plus répandu pour garantir qu’une exécution de
t...
@ Vincent Englebert - UNamur 13
Soient deux transactions T1 et T2 qui accèdent à deux ressources X et Y.
T1 ≡ [ W ← X ; Y ...
@ Vincent Englebert - UNamur 14
Le two-phase locking
Une transaction procède en deux phases
Phase 1: prendre des verrous s...
@ Vincent Englebert - UNamur 15
Le gestionnaire de verrous
Opérations
Lock(transaction id, ressource id, mode de verrou)
o...
@ Vincent Englebert - UNamur 16
Granularité
Plus la portée du verrou
sera petite
Moins il y aura de
conflits entre les
tra...
@ Vincent Englebert - UNamur 17
Deadlock
Un deadlock survient lorsque une transaction T1 nécessite une
ressource verrouill...
@ Vincent Englebert - UNamur 18
Timeout-based detection
Si les transactions durent moins de 15 secs, et qu’une transaction...
@ Vincent Englebert - UNamur 19
Graph-based detection
Représenter les dépendances entre transactions dans un graphe et
ana...
@ Vincent Englebert - UNamur 20
Deadlocks distribués
From: Martin
To: Peggy
Qtt: 100
From: Peggy
To: Martin
Qtt: 200
Begin...
@ Vincent Englebert - UNamur 21
Performances
1% deadlock : pose peu de problèmes
Observations:
K: nombre de demandes d’écr...
@ Vincent Englebert - UNamur 22
Lock conversion
une transaction demande un verrou en lecture et demande ensuite de
commute...
@ Vincent Englebert - UNamur 23
Arsenal
augmenter le nombre de verrous, i.e., diminuer la granularité
pour une table, fair...
@ Vincent Englebert - UNamur 24
Techniques d’optimisation
Écourter au maximum la durée de vie des verrous
Postposer les op...
@ Vincent Englebert - UNamur 25
Degree isolation 2 / cursor stability
Affaiblir les exigences d’une transaction
dans l’aid...
@ Vincent Englebert - UNamur 26
Degree isolation 1 / dirty reads
Aucun lock durant la lecture d’une information.
On peut d...
@ Vincent Englebert - UNamur 27
Intention lock / intention de verrouillage
Un intention lock est un pseudo-verrou que l’on...
@ Vincent Englebert - UNamur 28
Banque
NamurTournai
Dupont Martin
#125
#126 #127
#124
#123
T1: somme des avoirs de Monsieu...
@ Vincent Englebert - UNamur 29
Gestion de la concurrence entre transactions
La gestion de la concurrence avec des verrous...
@ 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
r...
@ Vincent Englebert - UNamur 32
HypothèsesHypothèses
Une transaction provoque un abort si elle rencontre un problème, et p...
@ Vincent Englebert - UNamur 33
Les deux phasesLes deux phases
Phase 1
s’assurer que chaque gestionnaire est prêt à faire ...
@ Vincent Englebert - UNamur 34
Coordinateur Gestionnaire Gestionnaire Gestionnaire
request-to-prepare
prepared
abort
done...
@ Vincent Englebert - UNamur 35
Les moments entre lesquels un gestionnaire émet le message
« prepared » et reçoit la requê...
@ Vincent Englebert - UNamur 36
Gestion des échecs de transmissionGestion des échecs de transmission
Point de vue du coord...
@ Vincent Englebert - UNamur 37
Du point de vue du gestionnairegestionnaire
Réception du message « request-to-prepare »
ap...
@ Vincent Englebert - UNamur 38
Gestion des crashesGestion des crashes
Écrire la liste des gestionnaires
participant à la ...
@ Vincent Englebert - UNamur 39
Gestion Crash Coordinateur
CRASH PHASE 1
Rien n'a été entrepris. Pas de problème donc.
CRA...
@ Vincent Englebert - UNamur 40
Écrire le mot prepared dans le Log
quand toutes les informations
nécessaire à un recovery ...
@ Vincent Englebert - UNamur 41
Gestion Crash Gestionnaire
CRASH PHASE A
Le gestionnaire trouve le log file vide: les info...
@ Vincent Englebert - UNamur 42
Transactions imbriquées
Une transaction imbriquée est un arbre de transactions qui sont el...
@ 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 o...
@ Vincent Englebert - UNamur 46
@ENCINA from IBM
Nested and top-level transactions
As described in the previous section, a...
@ Vincent Englebert - UNamur 47
@ENCINA from IBM
error_status_t OrderItem(idl_ulong_int stockNum,
idl_ulong_int numOrdered...
@ 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
t...
@ Vincent Englebert - UNamur 49
Exemple: XA-protocole
@ Vincent Englebert - UNamur 50
Les Transactions et CORBA
OTS (Object Transaction Service)
OTS est une description en term...
@ Vincent Englebert - UNamur 51
@ Vincent Englebert - UNamur 52
Transaction dans un exemple 3-tiers
Client
Transactionnel
Client
Transactionnel
Objet
Tran...
@ Vincent Englebert - UNamur 53
@ Vincent Englebert - UNamur 54
Les concepts
Client Transactionnel
Programme pouvant invoquer des opérations sur des objet...
@ Vincent Englebert - UNamur 55
Types de transactions
Le Service Transactions de CORBA fournit les interfaces pour gérer
d...
@ Vincent Englebert - UNamur 56
InterfaceInterface ControlControl
Représente le concept de transaction (simple ou imbriqué...
@ Vincent Englebert - UNamur 57
Interface CurrentInterface Current
Associé à tout objet qui hérite de l'interface Transact...
@ Vincent Englebert - UNamur 58
Programmation expliciteProgrammation explicite
le programmeur doit gérer explicitement la ...
@ Vincent Englebert - UNamur 59
Programmation impliciteProgrammation implicite
tout type d'objet qui participe à une trans...
@ Vincent Englebert - UNamur 60
module CosTransactions {
enum Status { StatusActive, StatusMarkedRollback, StatusPrepared,...
@ Vincent Englebert - UNamur 61
interface TransactionFactory {
Control create(in unsigned long time_out);
Control recreate...
@ Vincent Englebert - UNamur 62
interface Coordinator {
Status get_status();
Status get_parent_status();
Status get_top_le...
@ Vincent Englebert - UNamur 63
interface TransactionalObject {};
interface Synchronization : TransactionalObject {
void b...
@ Vincent Englebert - UNamur 64
Vue d'ensemble du module OTS
Terminator
commit
rollback
Coordinator
register_resource
Reso...
@ Vincent Englebert - UNamur 65
:CoordinatorFrom:account
(Resource)
To:Account
(Resource)
:CurrentClient:App.exe
begin()
d...
From:account :XADataStore To:Account :XADataStore :CoordinatorClient:App.exe
Begin()
Commit()
Debit(100)
Credit(100)
Regis...
@ Vincent Englebert - UNamur 67
Exemple: transfert bancaireExemple: transfert bancaire
#include <CosTransactions.idl>
modu...
@ Vincent Englebert - UNamur 68
class Client {
void main(){
org.omg.CosTransactions.Current current = null;
org.omg.CORBA....
@ Vincent Englebert - UNamur 69
package WithResource;
public class BankServer {
public static void main( String [] args ) ...
@ Vincent Englebert - UNamur 70
package WithResource;
public class BankImpl extends BankPOA {
private java.util.Hashtable ...
@ Vincent Englebert - UNamur 71
package WithResource;
public class AccountImpl extends AccountPOA
{
float _balance;
privat...
@ Vincent Englebert - UNamur 72
...
public AccountResource get_resource() {
org.omg.CORBA.Object objPoa = null;
org.omg.Po...
@ Vincent Englebert - UNamur 73
package WithResource;
public class AccountResourceImpl extends AccountResourcePOA{
private...
@ Vincent Englebert - UNamur 74
...
public CosTransactions.Vote prepare() {
System.out.println("[ Resource for " + _name +...
@ Vincent Englebert - UNamur 75
public void forget() {
System.out.println("[ Resource for " + _name + " : Forget ]");
remo...
FIN
Prochain SlideShare
Chargement dans…5
×

Cours Transactions distribuées

1 037 vues

Publié le

Cours à propos des transactions distribuées: transactions, locking, 2-phase commit, OTS,

Publié dans : Logiciels
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
1 037
Sur SlideShare
0
Issues des intégrations
0
Intégrations
672
Actions
Partages
0
Téléchargements
0
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Cours Transactions distribuées

  1. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 30. @ Vincent Englebert - UNamur 30 Sérialisation des transactions Cfr. Slides LaTeX (sérialisation des transactions)
  31. 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. 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. 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. 34. @ Vincent Englebert - UNamur 34 Coordinateur Gestionnaire Gestionnaire Gestionnaire request-to-prepare prepared abort done prepared no
  35. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 49. @ Vincent Englebert - UNamur 49 Exemple: XA-protocole
  50. 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. 51. @ Vincent Englebert - UNamur 51
  52. 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. 53. @ Vincent Englebert - UNamur 53
  54. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 76. FIN

×