こう 聞かれます
- 「トランザクションとは
何ですか」 - 「A さんから B さん
へ送金する 処理で、 途中で 失敗したら どうなりますか」 - 「ACID とは
何ですか。 1 つずつ 説明してください」
面接官が 見ている点
- 送金のような
具体的な 例で、 なぜ要るのかを話せるか - コミットと
ロールバックの 働きを言えるか - ACID の 4 つを、
暗記ではなく 自分の 言葉で言えるか
短い答え
- トランザクションは、
いく つかの 書き込みを 「全部 やるか、 全部 やらないか」の 1 まとまりとして 扱う 仕組みです。 - 送金なら、
A さんの 残高を 減らすことと B さんの 残高を 増やす ことを 1 まと まりにし、 片方だけ 起きた 状態を 残しません。 - 全部
うまく いったら コミットで 確定し、 途中で 失敗したら ロールバックで 始める 前の 状態に 戻します。
少し 詳しい答え
送金の例
BEGIN で
SQL クエリ
CREATE TABLE accounts (
id INTEGER PRIMARY KEY,
name VARCHAR(20),
balance INTEGER
);
INSERT INTO accounts VALUES
(1, 'Aya', 10000),
(2, 'Ken', 0);
BEGIN;
UPDATE accounts
SET balance = balance - 3000
WHERE id = 1;
UPDATE accounts
SET balance = balance + 3000
WHERE id = 2;
COMMIT;
SELECT name, balance
FROM accounts
ORDER BY id;Aya|7000
Ken|3000次は、
SQL クエリ
BEGIN;
UPDATE accounts
SET balance = balance - 3000
WHERE id = 1;
ROLLBACK;
SELECT name, balance
FROM accounts
ORDER BY id;Aya|7000
Ken|3000Aya さんの
ACID を 自分の言葉で
- 原子性 (Atomicity) 全部
やるか、 全部 やらないか。 途中までの 状態を 残しません - 一貫性 (Consistency) 表に
決めた 約束 (残高は マイナスに しない、のような 制約) を、 終わった あとも守ります - 独立性 (Isolation) 同時に
動く ほかの トランザクションと、 互いに 邪魔を しないようにします。 途中の 状態が どこまで 見えるかは、 設定 (分離レベル) で選びます - 永続性 (Durability) コミットが
済んだ 結果は、 その あと 電源が 落ちても 消えません
作った
よく ある間違い
- 「トランザクションを
使えば、 同時の 書き込みも 全部 安全」と言う 2 人が 同時に 同じ 残高を 読んで 書き戻すと、 片方の 更新が 消える ことがあります。 分離レベルや 行の 鍵 (ロック) で 別に 手当てします - ACID を
英語の 言葉の 暗記で答える 1 つずつ 「何が 起きないように するか」を、 送金の 例に 当てて話すと 伝わります - 外部の
サービスへの 送信も、 ロールバックで 取り消せると思う 戻せるのは DB の 中の 書き込みだけです。 送った メールや 外の 決済は、 別の 手当てが要ります
深掘りの問い
- 「残高が
足りないのに 送金されるのを、 どう 防ぎますか」 減らす更新に balance >= 3000のような条件を 付け、 更新できた 行が 0 なら ロールバックする、 または 残高を 読むときに 行を 鍵で 押さえる、と答えます - 「分離レベルとは
何ですか」 同時に 動く トランザクションの 途中の 結果を、 どこまで 見えなく するかの 段階です。 強く すると 安全ですが、 待ちや 失敗が 増える、と答えます - 「トランザクションを
長く 開いたままに すると、 何が 困りますか」 押さえた 行を、 ほかの 処理が 待ち続けます。 外の API の 返事を 待つ処理は トランザクションの 外に 出す、と答えます