Skip to content
Snippets Groups Projects
Commit 183135b9 authored by Robin VAN DE MERGHEL's avatar Robin VAN DE MERGHEL :computer:
Browse files

Adding DB imp

parent f8d47167
No related branches found
No related tags found
No related merge requests found
# Exercice 1
> **Créer les tables du schéma en choisissant le type de chaque colonne à l’aide des informations suivantes :**
> — CCheque et CEpargne contiennent le numéro du client propriétaire du compte et son solde qui peut être négatif.
> — DecisionCredit contient le dossier des demandes de crédit de chaque client avec la décision
> associée (OK si elle est acceptée, KO sinon).
```plantuml
@startuml
!define primary_key(x) <b><u><color:#b8861b><&key></color> x</u></b>
!define foreign_key(x) <color:#aaaaaa><&key></color> x
!define column(x, y) <color:#aaaaa>x</color> <color:#588157>y</color>
!define table(x) entity x << (T, white) >>
!define constraint(x) <color:#aaaaaa><:261D:></color> x
table(CCheque) {
column(primary_key, "numClient") int
column(foreign_key, "solde") int
}
table(CEpargne) {
column(primary_key, "numClient") int
column(foreign_key, "solde") int
}
table(DecisionCredit) {
column(primary_key, "numClient") int
column(foreign_key, "decision") varchar
}
@enduml
```
```sql
CREATE TABLE CCheque (
numClient INT PRIMARY KEY,
solde INT
);
CREATE TABLE CEpargne (
numClient INT PRIMARY KEY,
solde INT
);
CREATE TABLE DecisionCredit (
numClient INT PRIMARY KEY,
decision VARCHAR(2)
);
```
> **Insérer les données suivantes dans les tables :**
```sql
INSERT INTO CCheque VALUES (1, 1000);
INSERT INTO CCheque VALUES (2, 2000);
INSERT INTO CCheque VALUES (3, 3000);
INSERT INTO CCheque VALUES (4, 4000);
INSERT INTO CEpargne VALUES (1, 1000);
INSERT INTO CEpargne VALUES (2, 2000);
INSERT INTO CEpargne VALUES (3, 3000);
INSERT INTO CEpargne VALUES (4, 4000);
```
# Exercice 2
Au cours de cet exercice, assurez-vous que suffisamment de données soient insérer dans la base pour répondre aux questions. On supposera que chaque client a déjà un compte chèque et un compte
épargne.
## Question 1
> **On souhaite implémenter la procédure epargner(c, m) qui permet de transférer le montant m du compte chèque d’un client vers son compte épargne, uniquement dans le cas où le solde du compte chèque reste positif. Pour se faire, nous allons utiliser le langage PL/SQL, en complétant la procèdure ci-dessous :**
```sql
CREATE OR REPLACE PROCEDURE epargner ( c NUMBER, m NUMBER) AS
v_solde NUMBER;
BEGIN
SELECT solde INTO v_solde FROM CCheque WHERE client=c ;
DBMS_OUTPUT. PUT_LINE ( 'SoldeCheque : ' | | v_solde ) ;
END;
/
```
> **Pour voir les sortie de la procédure, il faut activer leur affichage avec :**
```sql
SET SERVEROUTPUT ON
```
On modifie la procédure pour qu’elle effectue le transfert de fonds si le solde du compte chèque est positif.
```sql
CREATE OR REPLACE PROCEDURE epargner (c NUMBER, m NUMBER) AS
v_solde NUMBER;
BEGIN
SELECT solde INTO v_solde FROM CCheque WHERE numClient=c ;
DBMS_OUTPUT. PUT_LINE ( 'SoldeCheque : ' || v_solde ) ;
IF v_solde > 0 THEN
UPDATE CCheque SET solde = solde - m WHERE numClient = c;
UPDATE CEpargne SET solde = solde + m WHERE numClient = c;
END IF;
END;
/
```
## Question 2
> **Modifier votre procèdure pour epargner (c NUMBER, m NUMBER, delai NUMBER) en insérant la commande DBMS_SESSION.sleep(delai); pour simuler un délai entre certaines des opérations effectuée. Utilisez ce délai pour obtenir une exécution en parallèle de deux de ces transferts vers le compte épargne d’un même client telles que le solde chèque du client devienne négatif à cause d’une lecture non reproductible.**
```sql
CREATE OR REPLACE PROCEDURE epargner (c NUMBER, m NUMBER, delai NUMBER) AS
v_solde NUMBER;
BEGIN
SELECT solde INTO v_solde FROM CCheque WHERE numClient=c ;
DBMS_OUTPUT. PUT_LINE ( 'SoldeCheque : ' || v_solde ) ;
IF v_solde > 0 THEN
DBMS_SESSION.sleep(delai);
UPDATE CCheque SET solde = solde - m WHERE numClient = c;
DBMS_SESSION.sleep(delai);
UPDATE CEpargne SET solde = solde + m WHERE numClient = c;
END IF;
END;
/
```
## Question 3.
> **Implémentez une nouvelle procédure traitementCredit(c, m), qui inscrit une nouvelle décision de crédit. Si le montant de crédit demandé m est 3 fois supérieur à la somme des soldes de ces comptes chèques et épargne, le crédit est accepté, sinon, la demande de crédit est rejetée.**
```sql
CREATE OR REPLACE PROCEDURE traitementCredit (c NUMBER, m NUMBER) AS
v_soldeCheque NUMBER;
v_soldeEpargne NUMBER;
BEGIN
SELECT solde INTO v_soldeCheque FROM CCheque WHERE numClient=c ;
SELECT solde INTO v_soldeEpargne FROM CEpargne WHERE numClient=c ;
IF m > 3 * (v_soldeCheque + v_soldeEpargne) THEN
INSERT INTO DecisionCredit VALUES (c, 'OK');
ELSE
INSERT INTO DecisionCredit VALUES (c, 'KO');
END IF;
END;
/
```
## Question 4
> **Ajoutez aussi un délai à la procédure traitementCredit. Exécuter en parallèle un traitement de crédit avec un transfert, si bien que le crédit soit accepté ou refusé alors qu’il n’aurait pas dû l’être.**
```sql
CREATE OR REPLACE PROCEDURE traitementCredit (c NUMBER, m NUMBER, delai NUMBER) AS
v_soldeCheque NUMBER;
v_soldeEpargne NUMBER;
BEGIN
SELECT solde INTO v_soldeCheque FROM CCheque WHERE numClient=c ;
SELECT solde INTO v_soldeEpargne FROM CEpargne WHERE numClient=c ;
IF m > 3 * (v_soldeCheque + v_soldeEpargne) THEN
DBMS_SESSION.sleep(delai);
INSERT INTO DecisionCredit VALUES (c, 'OK');
ELSE
DBMS_SESSION.sleep(delai);
INSERT INTO DecisionCredit VALUES (c, 'KO');
END IF;
END;
/
```
# Exercice 3
Oracle permet d’appliquer un verrou sur une table dans une transaction pour limiter les opérations des autres transactions sur cette table. Il y a deux modes de verrous :
— SHARE permet les lectures depuis les autres transactions, mais bloque les écritures,
— EXCLUSIVE bloque les écritures et les lectures des autres transactions.
On pose un verrou en utilisant une commande de la forme suivante :
```sql
LOCK TABLE DecisionCredit IN SHARE MODE;
```
À la fin de la transaction, le verrou est automatiquement libéré.
## Question 5
> **Tester les compatibilités entre les différents modes de verrous. Est-ce qu’une transaction peut prendre un verrou SHARE ou EXCLUSIVE lorsqu’une autre transaction détient un verrou SHARE ou EXCLUSIVE sur la même table ?**
On LOCK la table DecisionCredit en SHARE MODE dans une transaction, puis on tente de LOCK la table en EXCLUSIVE MODE dans une autre transaction.
```sql
LOCK TABLE DecisionCredit IN SHARE MODE;
```
```sql
LOCK TABLE DecisionCredit IN EXCLUSIVE MODE;
```
On a la seconde transaction qui bloque, car la première transaction a déjà un verrou sur la table.
On peut désactiver le verrou de la table en utilisant la commande suivante :
```sql
ALTER TABLE DecisionCredit NOLOCK;
```
File added
---
title: "CM4 Implémentation BDD"
author: "Robin VAN DE MERGHEL"
date: "2023-26-04"
lang: fr
geometry: margin=2cm
---
# Rappel du cours précédent
```mermaid
graph LR
A[Sériasabilité par conflit] --> B[Sériasabilité]
C[Équivalence par conflit] --> D[Équivalence]
A --> C
B --> D
C --> E[Conflit]
```
![Image Avec l'équation au dessus](./img/Exemple%20Rappel.jpg)
On a montré par inversions successives que $E_0$ est équivalente par conflit à $(T_1,T_2)$. Cela constitue une preuve de la sériabilité par conflit de $E_0$, donc $E_0$ est sériable.
# Graphe de précédence
On utilise le graphe de précédence pour décider si une exécution est sérialisable par conflit.
Pour une exécution donnée, on organise ses transactions vis à vis d'un ordre de précédence.
## Définition
On dit que $T_i$ précède $T_j$ dans une exécution $E_1$ noté $T_i \prec_{E_1} T_j$ s'il y a deux opérations $O_i$ dans $T_i$ et $O_j$ dans $T_j$ dans $T_j$ telles que :
1. $O_i$ précède $O_j$ dans $E_1$.
2. $O_i$ et $O_j$ s'applique sur le même élément de la base de données.
3. $O_i$ et $O_j$ sont des opérations d'écriture.
### Exemple
$$\begin{aligned}
E &= W_2(X) \ R_1(X) \ R_3(X) \ W_1(X) \ W_2(X) \ R_3(Y) \ R_2(Z) \ R_3(Z)\\
\end{aligned}$$
![Image Avec l'équation au dessus](./img/Equation.jpg)
**Remarque** : $T_i \prec_E T_j$ à cause de $O_i$ et $O_j$, alors on sait que l'ordre $O_i$ et $O_j$ ne pourra pas être inversé dans les exécution équivalentes par conflit à $E$.
De plus, si $E$ est sérialisable par conflit, dans toute exécution en série équivalente par conflit à $E$, $T_i$ apparaîtra nécessairement avant $T_j$.
## Définition
Le graphe de précédence d'une exécution $E$ est un graphe orienté où :
- les noeuds du graphe sont les transactions de $E$
- il y a une arrête de $T_i$ vers $T_j$ si $T_i \prec_{E} T_j$
### Exemple
Le graphe de précédence du dernier exemple :
```mermaid
graph LR
T2 --> T1
T2 --> T3
T3 --> T1
```
## Proposition
Une exécution est sérialisable par conflit si et seulement si son graphe de précédence ne contient pas de cycle (acyclique).
### Exemple
$$\begin{aligned}
E' &= R_2(A) \ R_1(B) \ W_2(A) \ R_2(B) \ R_3(A) \ W_1(B) \ W_3(A) \ W_2(B)
\end{aligned}$$
![Exemple 2](img/Exemple2.jpg)
On obtient comme données :
- $T_2\prec_{E'}T_3$
- $T_1\prec_{E'}T_2$
- $T_2\prec_{E'}T_1$
On obtient le graphe suivant :
```mermaid
graph LR
T1 --> T2
T2 --> T3
```
## Proposition
Si $E$ est sérialisable par conflit, alors $E$ est équivalente par conflit à toute exécution en série des transactions de $E$ où $T_i$ apparaît avant $T_j$ dès qu'il existe une arrête de $T_i$ vers $T_j$ dans le graphe de précédence de $E$.
### Exemple
Le graphe de précédence de l'exemple avec $E$ :
```mermaid
graph LR
T2 --> T1
T2 --> T3
T3 --> T1
```
On sait que $E$ est équivalente par conflit à $(T_2,T_3,T_1)$.
# Assurer la sériabilité à l'aide de verrous
En pratique : les opérations de chaque transaction arrivent dans un certain ordre au cours du temps. On ne chercher plus à savoir si l'exécution dans cet ordre est sérialisable, mais on cherche à différer certaines de ces opérations (un minimum) pour conserver la sérialisibilité.
Pour ce faire, les transactions vont poser des verrous sur les éléments de la base de données.
```mermaid
graph LR
A[Opération des transactions] --> B[Ordonnanceur]
B --> |Exécution sérialisable| DB[(BD)]
B --> C[(Taille des verrous)]
```
## Verrous
On considère deux types de verrous :
- **Verrou partagé** (shared lock) : nécessaire pour lire un élément
- **Verrou exclusif** (exclusive lock) : nécessaire pour écrire un élément
et des opérations correspondantes :
- $s_i(x)$ : la transaction $T_i$ obtient un verrou partagé sur l'élément $x$
- $x_i(x)$ : la transaction $T_i$ obtient un verrou exclusif sur l'élément $x$
- $u_i(x)$ : la transaction $T_i$ relâche ses verrous sur les éléments $x$
Dans une exécution, on dit que $T_i$ à un verrou partagé ou exclusif entre $s_i(x)$ (ou $x_i(x)$) et la première opération $u_i(x)$ qui suit.
### Exemple
$$\begin{aligned}
s_1(A) \ r_1(A) \ u_1(A) \ s_1(B) \ r_1(B) \ x_1(A) \ w_1(A) \ u_1(A) \ u_1(B)
\end{aligned}$$
![Exemple 3](img/exemple3.jpg)
Pour assurer le bon usage des verrous, on impose que :
- Sur chaque transaction $T_1$
- Une lecture $r_i(x)$ ne peut être exécutée que si $T_i$ a un verrou partagé ou exclusif sur $x$.
- Une écriture $w_i(x)$ ne peut être exécutée que si $T_i$ a un verrou exclusif sur $x$.
- Tous les verrous qui sont obtenus sont libérés avant la fin de la transaction.
- sur les exécutions, à chaque instant, un élément de la base peut-être
- Soit vérouillée de manière exclusive par une unique transaction $T_i$.
- Soit vérouillée de manière partagée par plusieurs transactions $T_i$.
- Mais pas les deux à la fois.
\ No newline at end of file
File added
File added
DB Implementation/img/Equation.jpg

581 KiB

File added
DB Implementation/img/Exemple Rappel.jpg

249 KiB

DB Implementation/img/Exemple2.jpg

268 KiB

DB Implementation/img/exemple3.jpg

407 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment