管理職サラリーマン。

様々な職種を経験してきた中途半端な管理職サラリーマンが贈るブログ

【超入門者向け】データベース(DB)のトランザクションを張るとは?

データベース(DB)は、IT業界にいると必ず言葉にしますよね。

この業界にいると、「DB(デービー)」と言ったりします。

また、この記事ではデータベースと書くと長いのでDBと略します。

IT業界で、しかもエンジニア職に着任したらDBから避ける方が難しいくらい、DBについては触れる機会が出てくるはずです。

私もそうでしたが、新卒の頃に「トランザクション」とか「ロールバック」とか「コミット」とかよく分からない用語がDBの話をする時に登場してきて、横文字やめてくれ!となってました。。

特に新卒時代は、DBを直接触る際に、必ず「トランザクション張ってからやれ!」とか言われました。

今回は、DBを触る上でも絶対に通る道「トランザクションを張る」ことの目的が、DBの超入門者に分かって頂ければと思って書いてみました!

1. そもそも「トランザクション」とは

トランザクションとは、「1つ以上の処理(更新、削除など)の単位」となります。

つまり、1つの処理でもトランザクション、10の処理でもトランザクション、1000の処理でもトランザクションとなります。

ただし、DB側はどの処理単位がひとまとまり(トランザクション)なのかは分かりません。

つまり、人間側でトランザクションの開始と終了を定義することで初めてトランザクションになります。
※実際にはDBの種類や設定によってもトランザクション開始と終了のしようは異なります

START TRANSACTION;

UPDATE TR_TABLE
SET NAME = 'TEST'
WHERE ID = 1;

UPDATE TR_TABLE
SET NAME = 'TEST2'
WHERE ID = 2;

COMMIT;

上記の例では、
トランザクション開始の合図: 「START TRANSACTION;」
トランザクション終了の合図: 「COMMIT;」
となります。

これがトランザクションになります。 ちなみに、コマンドは利用するDBによっても異なりますので、あくまでも一例として捉えてください。

「コミット(COMMIT)」がここで出てきましたね。

2. コミットとは

コミット(COMMIT)とは、トランザクションを終了させる処理を指します。

つまり、このデータ操作でおしまい!ってなったら、コミット(COMMIT)しましょう。

コミット処理が終了した段階で、DB側はデータ更新されます。

つまりコミットするまではDB側のデータは更新されません。

ここがポイントなんです!!

データ操作した後にselect(検索)してみて、「あっ、やばい。対象レコード以外も更新しちゃった!」なんてことが発生しても、コミットしなければデータ更新されてないので焦らなくて大丈夫。

3. ロールバックとは

前章の最後に書いた、
データ操作した後にselect(検索)してみて、「あっ、やばい。対象レコード以外も更新しちゃった!」なんてことが発生した時には、ロールバック(rollback)の出番です!

ロールバック(rollback)することで、コミット(COMMIT)時点までデータ操作を取り消すことができます!

コミット(COMMIT)しなければ、実際にはデータ更新されてないので、ロールバック(rollback)しちゃえばオッケーです。

4. トランザクションを張るのはなぜか

4.1 ACID特性でデータを正しく守る

トランザクションを張らないとデータの不整合が起こる場合があります。

Aさんの預金残高10万円で、Bさんの預金残高5万円の例を考えてみましょう。

  1. AさんがBさんに1万円を振り込み
  2. Aさんの預金残高を9万円(10万円-1万円)に更新
  3. Bさんの預金残高を6万円(5万円+1万円)に更新

2の処理は終了していて、3の処理中で障害発生したらどうでしょうか?

Aさんの残高が減っただけで、Bさんの残高は変わりません。これは大問題ですよね?

一連の処理セットが全て行われていない事象が発生します。

これを防止するのがACID特性と言われるもので、トランザクションを張る目的となります。

ACID特性とは、Atomicity(原子性)、Consistency(一貫性)、Isolation(分離性)、Durability(永続性)の頭文字を取って名付けられています。

  • AさんからBさんへの振り込みが一連の処理として行われる:「原子性」
  • Aさんから引かれた金額とBさんに振り込まれた金額が一致する:「一貫性」
  • Aさんから引かれる処理が他の処理により侵されない:「分離性」
  • トランザクションが終了した後の状態は、障害などがおきたとしても、その状態に変化はない:「永続性」

分かりやすい銀行振込みの例を出しましたが、トランザクションによって意図したデータ処理が守られているのはお分かり頂けましたでしょうか。

4.2 DB作業時のミス防止

結局は、コミット(COMMIT)しなければデータ更新されません。

そのため、いわゆる破壊系の処理をした際にちゃんとselectで確認して問題なければコミット(COMMIT)することができます。

(例)新卒の入門者レベルのDB作業ミス

  • まだコマンド打っている途中なのに誤ってEnterを押してしまった
  • 1行づつコピペでコマンドを入力していたが改行が誤って入ってしまい、確認前にデータ処理行われた
  • selectだけのつもりでトランザクションを張っていなかったがその後update処理もやってしまった

こんな感じのミスは私も見たことがあります。

いずれの場合も、意図したものとは異なるsql文を入れてしまっていなればインシデントにはなりませんが、意図したものと異なる命令文を実行した瞬間にインシデント発生という重大事故になってしまいます。

トランザクションを張って、明示的なコミット(COMMIT)をする運用であれば、ロールバック(rollback)できるのでインシデントは発生しにくい運用になると考えています。