· 6 years ago · Mar 18, 2019, 02:52 AM
1SET search_path = public;
2CREATE TABLE Accounts (
3acctID INTEGER NOT NULL PRIMARY KEY,
4balance INTEGER NOT NULL,
5CONSTRAINT remains_nonnegative CHECK (balance >= 0)
6);
7
8-- data
9DROP TABLE if EXISTS balancea CASCADE;
10DROP TABLE if EXISTS balanceb CASCADE;
11DELETE FROM Accounts;
12INSERT INTO Accounts (acctID, balance) VALUES (101, 1000);
13INSERT INTO Accounts (acctID, balance) VALUES (202, 2000);
14SELECT * FROM Accounts;
15
16
17--Q1 a
18
19-- TRANSACTION A
20
21
22-- TRANSACTION B
23
24
25-- TRANSACTION A
26
27
28
29-- TRANSACTION B
30
31
32-- TRANSACTION A
33
34
35-- TRANSACTION B
36
37
38-- data
39DROP TABLE if EXISTS balancea CASCADE;
40DROP TABLE if EXISTS balanceb CASCADE;
41DELETE FROM Accounts;
42INSERT INTO Accounts (acctID, balance) VALUES (101, 1000);
43INSERT INTO Accounts (acctID, balance) VALUES (202, 2000);
44SELECT * FROM Accounts;
45
46--- Q1 b
47
48-- TRANSACTION A
49
50
51-- TRANSACTION B
52
53
54-- TRANSACTION A
55
56
57-- TRANSACTION B
58
59
60-- TRANSACTION A
61
62
63-- TRANSACTION B
64
65
66-- Q2-a
67/*
68Le select de l'étape 3 de la transaction A donne un résultat différent du select de la 1re étape.
691re étape: Account 101 avec 1000 et 202 avec 2000 affichés
703e étape: Seulement 202 avec 2500 affiché
71Ainsi, l’account 101 n’est pas affiché, car la transaction 2 a réduit son solde à 500. Ceci est incohérent avec le premier select.
72*/
73-- data
74DROP TABLE if EXISTS balancea CASCADE;
75DROP TABLE if EXISTS balanceb CASCADE;
76DELETE FROM Accounts;
77INSERT INTO Accounts (acctID, balance) VALUES (101, 1000);
78INSERT INTO Accounts (acctID, balance) VALUES (202, 2000);
79SELECT * FROM Accounts;
80
81-- Transaction A
82\set AUTOCOMMIT off
83BEGIN;
84SET TRANSACTION
85ISOLATION LEVEL READ COMMITTED;
86--ISOLATION LEVEL REPEATABLE READ;
87SELECT * FROM Accounts
88WHERE balance > 500;
89
90-- Transaction B
91\set AUTCOMMIT off
92BEGIN;
93UPDATE Accounts
94SET balance = balance - 500
95WHERE acctID = 101;
96UPDATE Accounts
97SET balance = balance + 500
98WHERE acctID = 202;
99SELECT * FROM Accounts;
100COMMIT;
101
102-- Transaction A
103SELECT * FROM Accounts
104WHERE balance > 500;
105
106-- Q2-b
107/*
108REPEATABLE READ fait en sorte que le select de l'étape 1 de la transaction A soit cohérent avec celui de l'étape 3.
1091re étape: Account 101 avec 1000, account 202 avec 2000
1102e étape: Account 101 avec 1000, account 202 avec 2000
111La transaction B n'a donc pas influencé le select de la transaction A.
112*/
113-- data
114DROP TABLE if EXISTS balancea CASCADE;
115DROP TABLE if EXISTS balanceb CASCADE;
116DELETE FROM Accounts;
117INSERT INTO Accounts (acctID, balance) VALUES (101, 1000);
118INSERT INTO Accounts (acctID, balance) VALUES (202, 2000);
119SELECT * FROM Accounts;
120
121-- Transaction A
122\set AUTCOMMIT off
123BEGIN;
124SET TRANSACTION
125ISOLATION LEVEL REPEATABLE READ;
126-- ISOLATION LEVEL READ COMMITTED;
127SELECT * FROM Accounts
128WHERE balance > 500;
129
130
131-- Transaction B
132\set AUTCOMMIT off
133BEGIN;
134UPDATE Accounts
135SET balance = balance - 500
136WHERE acctID = 101;
137UPDATE Accounts
138SET balance = balance + 500
139WHERE acctID = 202;
140SELECT * FROM Accounts;
141COMMIT;
142
143-- Transaction A
144SELECT * FROM Accounts
145WHERE balance > 500;
146--- Q2-c
147/*
148Le problème est que même si la transaction B ajoute des données à la table Accounts, les selects de la transaction A
149n'arrive pas à les trouver et à les afficher.
150Transaction B (étape 2, 4) -> Accounts 301 et 302 avec un solde de 3000 insérés
151Transaction A (étape 3, 5) -> Les selects affichent seulement 1 account avec balance > 1000
152La transaction A ne parvient donc pas à sélectionner les insertions de la transaction B.
153*/
154-- data
155DROP TABLE if EXISTS balancea CASCADE;
156DROP TABLE if EXISTS balanceb CASCADE;
157DELETE FROM Accounts;
158INSERT INTO Accounts (acctID, balance) VALUES (101, 1000);
159INSERT INTO Accounts (acctID, balance) VALUES (202, 2000);
160SELECT * FROM Accounts;
161
162-- Transaction A
163\set AUTCOMMIT off
164BEGIN;
165SET TRANSACTION
166ISOLATION LEVEL REPEATABLE
167READ READ ONLY;
168-- Transaction B
169\set AUTCOMMIT off
170BEGIN;
171INSERT INTO Accounts (acctID,
172balance) VALUES (301,3000);
173
174-- Transaction A
175SELECT * FROM Accounts
176WHERE balance > 1000;
177
178-- Transaction B
179INSERT INTO Accounts (acctID,
180balance) VALUES (302,3000);
181
182-- Transaction A
183SELECT * FROM Accounts
184WHERE balance > 1000;
185COMMIT;
186
187-- Q4- Deadlock
188-- data
189DROP TABLE if EXISTS balancea CASCADE;
190DROP TABLE if EXISTS balanceb CASCADE;
191DELETE FROM Accounts;
192INSERT INTO Accounts (acctID, balance) VALUES (101, 1000);
193INSERT INTO Accounts (acctID, balance) VALUES (202, 2000);
194SELECT * FROM Accounts;
195
196--- Transaction A
197BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
198UPDATE Accounts
199SET balance = balance - 500
200WHERE acctID = 101;
201
202-- Transaction B
203BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
204UPDATE Accounts
205SET balance = balance - 700
206WHERE acctID = 202;
207UPDATE Accounts
208SET balance = balance + 700
209WHERE acctID = 101;
210COMMIT;
211
212--- Transaction A
213UPDATE Accounts
214SET balance = balance - 300
215WHERE acctID = 202;
216COMMIT;