「一連の処理」とは
• ロワール(did=c)のワインはもう売るのを辞めよう!
データベースシステム論 第回2016 [ 13 ] 11p.
wid name did price
1 シャブリ A 2400
2 ジュヴレシャンベルタン A 3000
3 サンテミリオン B 5800
4 オーメドック B 2200
5 サンセール C 2800
6 シャンパン D 4000
7 コンチャ・イ・トロ E 980
did district
A ブルゴーニュ
B ボルドー
C ロワール
D シャンパーニュ
E チリ
wine vineyard
1. wineテーブルからdidがCの行を削除
2. vineyardテーブルからdidがCの行を削除
ト
ラ
ン
ザ
ク
シ
ョ
ン
12.
ACID特性が無いと起こる問題
データベースシステム論 第 回2016[ 13 ] 12p.
1. wineテーブルからdidがCの行を削除
2. vineyardテーブルからdidがCの行を削除
1. wineテーブルにミュスカデを追加~♪
wid name did price
1 シャブリ A 2400
2 ジュヴレシャンベルタン A 3000
3 サンテミリオン B 5800
4 オーメドック B 2200
5 サンセール C 2800
6 シャンパン D 4000
1000 コンチャ・イ・トロ E 980
1001 ミュスカデ C 2100
did district
A ブルゴーニュ
B ボルドー
C ロワール
D シャンパーニュ
E チリ
wine vineyard
1001 ミュスカデ C 2100
ROLLBACKの動作
• トランザクションの開始
• wineテーブル全行削除
•確認(コミット前)
• トランザクションをアボート
• 確認(コミット後)
データベースシステム論 第 回2016 [ 13 ] 16p.
START TRANSACTION;
DELETE FROM wine;
SELECT * FROM wine;
ROLLBACK;
SELECT * FROM wine;
A
A
A
A
A
17.
ROLLBACKの動作 - 結果
データベースシステム論第 回2016 [ 13 ] 17p.
dbsys=# START TRANSACTION;;
START TRANSACTION
dbsys=# DELETE FROM wine;
DELETE 8
dbsys=# SELECT * FROM wine;
wid | name | did | price
-----+------+-----+-------
(0 行)
dbsys=# ROLLBACK;
ROLLBACK
dbsys=# SELECT * FROM wine;
wid | name | did | price
------+------------------------+-----+-------
1 | シャブリ | A | 2400
2 | ジュヴレシャンベルタン | A | 3000
3 | サンテミリオン | B | 5800
4 | オーメドック | B | 2200
5 | サンセール | C | 2800
6 | シャンパン | D | 4000
7 | コンチャ・イ・トロ | E | 980
(7 行)
18.
COMMITの動作
• トランザクションの開始
• wineテーブル一行追加
•確認①
• トランザクションをコミット
• 確認②
データベースシステム論 第 回2016 [ 13 ] 18p.
START TRANSACTION;
INSERT INTO wine VALUES(8,’ミュスカデ’,’C’,2100);
SELECT * FROM wine;
COMMIT;
SELECT * FROM wine;
A
A
A
A
A
SELECT * FROM wine; B
SELECT * FROM wine; B
19.
COMMITの動作 - 結果
•コミット前
データベースシステム論 第 回2016 [ 13 ] 19p.
dbsys=# START TRANSACTION;
START TRANSACTION
dbsys=# INSERT INTO wine VALUES(1001,'ミュスカデ','C',2100);
INSERT 0 1
dbsys=# SELECT * FROM wine;
wid | name | did | price
------+------------------------+-----+-------
1 | シャブリ | A | 2400
2 | ジュヴレシャンベルタン | A | 3000
3 | サンテミリオン | B | 5800
4 | オーメドック | B | 2200
5 | サンセール | C | 2800
6 | シャンパン | D | 4000
7 | コンチャ・イ・トロ | E | 980
8 | ミュスカデ | C | 2100
(8 行)
dbsys=# commit;
COMMIT
dbsys=# select * from wine;
wid | name | did | price
------+------------------------+-----+-------
1 | シャブリ | A | 2400
2 | ジュヴレシャンベルタン | A | 3000
3 | サンテミリオン | B | 5800
4 | オーメドック | B | 2200
5 | サンセール | C | 2800
6 | シャンパン | D | 4000
7 | コンチャ・イ・トロ | E | 980
(7 行)
A
B
ACID - 独立性:トランザクションAのコミット前の変更はBから見えない
20.
COMMITの動作 - 結果
•コミット後
データベースシステム論 第 回2016 [ 13 ] 20p.
dbsys=# START TRANSACTION;
START TRANSACTION
dbsys=# INSERT INTO wine VALUES(1001,'ミュスカデ','C',2100);
INSERT 0 1
dbsys=# SELECT * FROM wine;
wid | name | did | price
------+------------------------+-----+-------
1 | シャブリ | A | 2400
2 | ジュヴレシャンベルタン | A | 3000
3 | サンテミリオン | B | 5800
4 | オーメドック | B | 2200
5 | サンセール | C | 2800
6 | シャンパン | D | 4000
7 | コンチャ・イ・トロ | E | 980
8 | ミュスカデ | C | 2100
(8 行)
dbsys=# commit;
COMMIT
dbsys=# select * from wine;
wid | name | did | price
------+------------------------+-----+-------
1 | シャブリ | A | 2400
2 | ジュヴレシャンベルタン | A | 3000
3 | サンテミリオン | B | 5800
4 | オーメドック | B | 2200
5 | サンセール | C | 2800
6 | シャンパン | D | 4000
7 | コンチャ・イ・トロ | E | 980
8 | ミュスカデ | C | 2100
(8 行)
A
B
ACID - 独立性: Aがコミットした瞬間、Aによるデータの変更がBからも見える
テーブルのロック
データベースシステム論 第 回2016[ 13 ] 37p.
LOCK TABLE テーブル名
IN lockmode MODE;
求するロック
モード
現在のロックモード
ACCESS
SHARE
ROW SHARE
ROW
EXCLUSIVE
SHARE
UPDATE
EXCLUSIVE
SHARE
SHARE ROW
EXCLUSIVE
EXCLUSIVE
ACCESS
EXCLUSIVE
ACCESS
SHARE
X
ROW SHARE X X
ROW
EXCLUSIVE
X X X X
SHARE
UPDATE
EXCLUSIVE
X X X X X
SHARE X X X X X
SHARE ROW
EXCLUSIVE
X X X X X X
EXCLUSIVE X X X X X X X
ACCESS
EXCLUSIVE
X X X X X X X X
38.
テーブルのロック - SQL
•ワインテーブルをロックし確認
• 結果からロックが機能している事を確認せよ
• トランザクション終了と共にロックは解除
• 解除された事を確認せよ(どうやって?)
データベースシステム論 第 回2016 [ 13 ] 38p.
START TRANSACTION;
LOCK wine IN ACCESS EXCLUSIVE MODE;
SELECT * FROM wine;
SELECT * FROM wine;
A
B
A
COMMIT; もしくは ROLLBACK;
A
行のロック- SQL
• ワインテーブルのある行をロックし確認
•wid=1の行のみがロックされている事を確認
• 次にその行の価格を更新する
• トランザクション終了と共にロックは解除
• BのブロックされたSELECT文の出力はprice=100000?
データベースシステム論 第 回2016 [ 13 ] 40p.
START TRANSACTION;
SELECT * FROM wine WHERE wid = 1 FOR UPDATE;
START TRANSACTION;
SELECT * FROM wine WHERE wid = 2 FOR UPDATE;
SELECT * FROM wine WHERE wid = 1 FOR UPDATE; B
A
UPDATE wine SET price = 100000 WHERE wid = 1;
COMMIT;A