#15 Transactions

#15.0 Introduction

Transaction - ์œ ์ € ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹์€ sql ์ฝ”๋“œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ, ์—ฌ๋Ÿฌ sql ์ฟผ๋ฆฌ์— ๊ฑฐ์ณ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์„ ๊ฐ•์ œํ•ด์ฃผ๋Š” ๋“ฑ ์ค‘์š” ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ์‚ฐ์—…์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋…

Transaction Control Language

#15.1 Transaction Are Awesome

CREATE TABLE accounts (
  account_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  account_holder VARCHAR(100) NOT NULL,
  balance DECIMAL(10, 2) NOT NULL CHECK (balance >= 0)
);

drop table accounts;

INSERT INTO accounts (account_holder, balance) VALUES
('SON', 1000.00),
('KIM', 2000.00);

BEGIN; -- TRANSACTION ์‹œ์ž‘ // MYSQL์—์„œ๋Š” START TRANSACTION

  SELECT * FROM accounts;

  UPDATE accounts SET balance = balance + 1500 WHERE account_holder = 'SON';
  
  SELECT * FROM accounts;
  UPDATE accountS SET balance = balance - 1500 WHERE account_holder = 'KIM';

COMMIT; -- TRANSACTION ์ข…๋ฃŒ

SELECT * FROM accounts;

#15.2 ACID

transaction ์‹œ์Šคํ…œ์€ ACID ๋ผ๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.

Atomic - All or Nothing ๋ชจ๋“  ์ž‘์—…์ด ์„ฑ๊ณตํ•˜๊ฑฐ๋‚˜ ์ž‘๋™ํ•˜์ง€ ์•Š์•„์•ผ ํ•จ

Consistent - ์œ ํšจํ•œ(valid) ์ƒํƒœ์—์„œ ๋˜ ๋‹ค๋ฅธ ์œ ํšจ(valid) ์ƒํƒœ๊ฐ€ ๋˜์–ด์•ผ ํ•จ

Isolated - ํ•˜๋‚˜์˜ transaction์—์„œ ์‹คํ–‰๋œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด commit ๋˜๊ธฐ ์ „๊นŒ์ง€ ๋‹ค๋ฅธ transaction์—์„œ ํ™•์ธํ•  ์ˆ˜ ์—†์Œ

Durablity - transaction์ด ์‹คํ–‰๋˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ „์›์ด ๋‚˜๊ฐ€๊ฑฐ๋‚˜ ์„œ๋ฒ„๊ฐ€ ์ฃฝ๊ฑฐ๋‚˜ ํ•˜๋Š” ์ƒํ™ฉ์—๋„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋“ค์ด ์˜๊ตฌ์ ์œผ๋กœ ์œ ์ง€๋˜๋Š” ๊ฑธ ํ™•์‹ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

auto commit mode ์—์„œ๋Š” SELECT FROM, UPDATE, DELETE ๋“ฑ ๋ชจ๋“  ๋ช…๋ น๋ฌธ์ด ๊ทธ ์ž์ฒด๋กœ ํ•˜๋‚˜์˜ ์ž‘์€ transaction ์ทจ๊ธ‰๋จ

#15.3 Savepoints

like checkpoint in game

BEGIN;
  UPDATE accounts
  SET balance = balance + 1000
  WHERE acount_holde = 'KIM';
  
  SAVEPOINT transfer_one; -- ์—ฌ๊ธฐ๋กœ ROLLBACK
  
  SELECT * FROM accounts;
  
  UPDATE accounts
  SET account_holder = 'rich KIM'
  WHERE acount_holde = 'KIM';
  
  ROLLBACK TO SAVEPOINT transfer_one; -- ์ €์žฅํ•œ SAVE POINT๋กœ ์ด๋™
  ROLLBACK; -- ์ฒ˜์Œ์œผ๋กœ ์ด๋™

COMMIT;

#15.4 Read Uncommited ~

transaction์ด ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” 4๊ฐ€์ง€ Isolation Level

Isolation Level - transaction ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ฐ€์‹œ์„ฑ ์ˆ˜์ค€ ์ œ์–ด

Isolation Level

Read uncommitted

Read committed

Repeatable read

Serializable

Isolation Level์€ transaction phenomena๋ผ ์•Œ๋ ค์ง„ transaction์—์„œ ๋ฐœ์ƒํ•˜๋Š” ํ˜„์ƒ์„ ๋ง‰์•„์ฃผ๊ธฐ๋„ ํ•จ. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ „๋ฐ˜์— ์ผ๊ด€์„ฑ ์žˆ๋Š” ํ˜„์ƒ๋“ค๋กœ 4๊ฐ€์ง€ phenomena๋Š” Isolation ๋‚ด๋ถ€์—์„œ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์Œ, transaction ์ข…๋ฅ˜์— ๋”ฐ๋ผ 4๊ฐ€์ง€ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ ํƒ ๊ฐ€๋Šฅํ•จ

Dirty Read - transaction์ด commit ๋˜์ง€ ์•Š์€ transaction์ด ์ž‘์„ฑํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ์ฝ์„ ๋•Œ ๋ฐœ์ƒ

Nonrepeatable Read - transaction์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ ์ฝ์œผ๋ ค๊ณ  ํ•  ๋•Œ ๋ฐœ์ƒ, ์ด๋ฏธ ํ•œ๋ฒˆ ์ฝ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅธ transaction์—์„œ ์ˆ˜์ •๋˜๊ณ  commit ๋˜์—ˆ์„ ๋•Œ

Phantom Read - row(ํ–‰) ์ง‘ํ•ฉ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ transaction ์•ˆ์—์„œ ์žฌ์‹คํ–‰ํ•  ๋•Œ ์ตœ๊ทผ commit ๋œ ๋‹ค๋ฅธ transaction์— ์˜ํ•ด ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ์ด์ „๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ

Serialization Anomaly - ์—ฌ๋Ÿฌ transaction์˜ ์„ฑ๊ณต์ ์ธ ์ปค๋ฐ‹ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ˆœ์„œ๋กœ transaction์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š์„ ๋•Œ ๋ฐœ์ƒ

---

Locks - ๋‹ค๋ฅธ transaction์—์„œ ๋™์‹œ์— ๊ฐ™์€ row ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ ค ํ•  ๋•Œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ž๋™์œผ๋กœ lock ๊ฑธ์–ด ์ˆœ์„œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋„๋ก ํ•จ

row๋ฅผ lock ํ•ด ์•„๋ฌด๋„ ํ•ด๋‹น row๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋„๋ก

SELECT โ€” FOR UPDATE; ๋ชจ๋ฅด๋Š” ์‚ฌ์ด์— ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Œ exclusive lock ์•„๋ฌด๋„ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •, ์‚ญ์ œํ•  ์ˆ˜ ์—†์Œ

SELECT โ€” FOR SHARE; ๋ชจ๋ฅด๋Š” ์‚ฌ์ด์— ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Œ ๋‹ค๋ฅธ FOR SHARE ์ฟผ๋ฆฌ์—์„œ ๊ฐ™์€ lock์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•จ

Last updated

Was this helpful?