データベースの変更をちゃんとコントロールして正しく実行するために、PostgreSQLではトランザクションっていう考え方を使うよ。これは複数のSQL操作をひとまとまりで実行する仕組み。もし何かミスったら、その変更を全部取り消せる。ここでBEGIN、COMMIT、ROLLBACKのコマンドが活躍するんだ。
トランザクションコマンドは単なるお作法じゃなくて、エラーや障害からデータを守る超重要な役割を持ってる。複数のSQL操作を実行するとき、全部ちゃんと動くかどうかが大事。もし1つでも失敗したら、データベースは元の状態に戻さなきゃいけない。これがトランザクションコマンドが必要な大きな理由のひとつ。データの一貫性を守ってくれるんだ。
さらに、トランザクションは「アトミック性」も保証してくれる。つまり、全部の変更が一緒に反映されるか、全く反映されないかのどっちか。例えば、お金だけ引き落とされて商品が注文に追加されない、みたいな「半端な更新」が起きないようにしてくれる。
もちろん、トランザクションは柔軟性もバッチリ。複雑な処理の流れを作ったり、どこでCOMMITしてどこでROLLBACKするかを自分でコントロールできるし、SAVEPOINTで部分的に巻き戻すこともできる。これでデータベース操作が安全で、しかも思い通りにできるんだ。
BEGINコマンド
BEGINコマンドはPostgreSQLに「これからトランザクション始めるよ」って伝えるもの。この後にやる変更は、COMMITで確定するかROLLBACKで取り消すまで「保留」状態になる。
よくある例:例えば、ある口座から別の口座に100単位のお金を移したいとき。まずBEGINでトランザクションを始める:
BEGIN;
-- トランザクション開始
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- 口座1の残高を減らした
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- 口座2の残高を増やした
トランザクション中に実行したコマンドの変更は、他のユーザーからは見えないよ。COMMITした後に初めて見えるようになる。
COMMITコマンド
COMMITコマンドはトランザクションを終了して、その中でやった変更をデータベースに保存する。これを実行すると、変更が全ユーザーに見えるようになる。
トランザクションを終わらせる例:
COMMIT;
-- トランザクション内の全変更が保存された
これでさっきの残高変更も「確定」した状態。お金の移動が無事に完了したってこと。
ROLLBACKコマンド
もしトランザクション中にミスに気づいたり、やっぱり変更をやめたいと思ったら、ROLLBACKコマンドを使おう。これはBEGIN以降の操作を全部取り消してくれる。
例えば、お金を移す途中で残高不足に気づいた場合、こうやってトランザクションを巻き戻す:
BEGIN;
-- トランザクション開始
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- あっ、エラー:残高が足りない。
ROLLBACK;
-- 全ての変更が取り消され、データベースは元の状態に戻る
ROLLBACKの後は、データベースに何も変更が残らない。ミス防止にめっちゃ便利。
完全な例:口座間のお金の移動
じゃあ全部まとめてみよう。これは残高チェック、お金の移動、エラー時の巻き戻しまで含めたトランザクションの完全な例だよ:
BEGIN;
-- トランザクション開始
-- 口座の残高をチェック
SELECT balance INTO current_balance FROM accounts WHERE account_id = 1;
-- 残高が十分か確認
IF current_balance >= 100 THEN
-- 十分ならお金を移動
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;
-- 変更を確定
ELSE
-- 残高不足ならトランザクションを取り消し
ROLLBACK;
END IF;
この例で、トランザクションコマンドがどうやってデータの不整合を防ぐかが分かるね。
IF THEN ELSE END IFはストアドプロシージャの操作で、これはもうちょい進んだら解説するね:P
オートコミット設定の特徴
PostgreSQLはデフォルトでオートコミットモードになってる。つまり、明示的なトランザクション外でコマンドを実行すると、その場で即コミットされる。例えば:
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- COMMITしなくてもすぐに変更が保存される
トランザクションを自分で管理したいなら、必ずBEGINで明示的にトランザクションを始めよう。
今のセッションだけオートコミットをオフにしたい場合は、こうやって設定できる:
SET AUTOCOMMIT TO OFF;
注意:オートコミットをオフにしたら、毎回COMMITかROLLBACKでセッションを終わらせる必要があるよ。
トランザクション操作でよくあるミス
COMMITのし忘れ。 COMMITを忘れると、変更が未完了のままセッション終了時に消えちゃう。
ロック。 トランザクションが終わるまで使ってるリソースがロックされたままになる。他の人が同じデータにアクセスできなくて困ることも。
無駄なROLLBACK。 プログラマーが慎重すぎて、必要ないのにトランザクションを巻き戻しちゃうことがある。これだと再計算が増えてDBに負荷がかかる。
ハングしたトランザクション。 トランザクションを始めたのにCOMMITもROLLBACKもせずに放置すると、セッションがハングしてDBリソースがロックされる原因になる。
実践での使いどころ
開発者やDBA(データベース管理者)の面接で、PostgreSQLのトランザクション実装について聞かれることがある。BEGIN、COMMIT、ROLLBACKを理解してると、安全かつ効率的にデータを扱えるってアピールできるよ。
実際、トランザクションは信頼性の高いシステム作りに超便利。例えばネットショップの注文処理や、ポイント計算のロジックなんかで大活躍。
これでトランザクションの基本コマンドはバッチリだね。次はSAVEPOINTの使い方や、分離レベルの話とか、もっと面白いトピックに進もう。PostgreSQLは本当に奥が深いから、覚悟してね。
GO TO FULL VERSION