
【Java】トランザクション処理について
「トランザクション処理」という言葉は基幹システムや、オンライン決済など、データの整合性と信頼性を必要とするシステムを開発する際に必ず耳にすると思います。
必ず耳にするということは大事な処理であるということだというのはわかるはずです。
ただ、どういった処理なのかぼんやりとしか分からない方もいると思います。
私もその一人でしたので、今回は学習した内容をまとめると同時に分かりやすく「トランザクション処理」について解説していきたいと思います。
1. トランザクション処理とは

まずはトランザクションについて解説します。
トランザクションとは、もともと「商取引」を意味するビジネス用語で、IT分野ではソフトウェアの処理方式のことを指し、処理の一貫性を持たせるために「データベース管理システム」で活用されています。
つづいてトランザクション処理についてです。
トランザクション処理とは、相互依存の関係にある複数の処理を1つの処理単位にまとめて、矛盾なく処理することで、データベースにおいて、処理の一貫性を持たせるために、複数の処理を1つの処理として実行して管理する仕組みで、データの整合性を保つための要素の1つです。
というように難しい言葉で表すとこのようになります。
簡単に言うと一連のデータ処理の途中で問題が起こった場合、それまでの操作をすべて元に戻すという処理です。
この処理を行うことでデータの不整合を防ぐことができます。
例を交えて簡単に説明します。
実際の処理で例えると、クレジットカードで商品を購入した時にクレジット会社に購入可能かどうかOKを貰って、売上を確定させるまでの処理をまとめたものになります。
もし処理が別々の場合、複数の商品を購入した時に1点目は購入できて2点目にエラーが発生した場合そこで処理が中断してしまいデータベースに矛盾が生じてしまいます。
そのため、トランザクション処理ではエラーが発生した場合注文処理自体をまとめて中止します。
トランザクション処理が持つ性質を1970年代後半にジム・グレイという方がACID特性という4つの特性を提唱しています。
2. ACID特性

ここではACID特性についてATM内での処理を例に挙げて説明します。
1.不可分性(Atomicity)
トランザクションに含まれるタスクが全て実行されるか、もしくは全く実行されないことを保証する性質のことをいいます。
アトミック性、原子性とも呼ばれたりします。
下記が一例になります。
口座Aから口座Bに対し1万円送金する場合を考えた場合、送金操作は下記の2つの操作によって行われます。
1. 口座Aの残高から1万円を引く
2. 口座Bの残高に1万円を加える
不可分性が保証されるというのは、上の操作1、2が全て行われるか、あるいは全く行われないことを指します。
なぜならどちらか片方だけが実行された場合、銀行全体の預金残高に矛盾が発生してしまうからです。
2.一貫性(Consistency)
トランザクション開始と終了時にあらかじめ与えられた整合性を満たすことを保証する性質を指します。
日本語では一貫性あるいは整合性とも呼ばれる。
すなわち、データベースのルール、つまりトランザクションが終了した時に実行前と実行後のデータに矛盾が生じないようにすることです。
預金残高を例にすると、その値は一般的に0あるいはプラスの値を取る条件を満たす必要がある。
よって、口座Aから送金を行うとき、その前後でAの口座残高がマイナスになるような額は送金できないようにします。
つまり10000円の残高から20000円の金額が引き落とせないようにしていると言うことです。
このようなルールを保証するのが一貫性の役割です。
3.独立性(Isolation)
トランザクション中に行われる操作の過程が他の操作から隠されることを指しており、日本語では分離性、独立性または隔離性ともいいます。
より形式的に解説すると、独立性とはトランザクション履歴が直列化されていることと言えます。
この性質と性能はトレードオフの関係にあるため、一般的にはこの性質の一部を緩和して実装される場合が多くなります。
預金残高の例で考えてみると、残高100万円の口座Aから残高200万円の口座Bに1万円送金する場合の操作が
1. 口座Aの残高から1万円を引く
2. 口座Bの残高に1万円を加える
の順序で行われたとします。
その時の内部状態は、
時点 口座A 口座B
送金前 100万円 200万円
実行中 99万円 200万円
送金後 99万円 201万円
このように3つになりますが、外部や操作してる人からは送金前と送金後のいずれかの状態しか確認できません。
4.永続性(Durability)
トランザクション操作の完了通知を操作した人が受けた時点で、その操作は永続的となり、結果が失われることがないということを指します。
永続性あるいは持続性とも呼ばれます。これはシステム障害に耐えるということであり、データベース管理システムは整合性制約をチェック済みでありトランザクションを中止してはいけないということです。
多くのデータベース実装では、トランザクション操作を永続性記憶装置上にログとして記録し、システムに異常が発生したらそのログを用いて異常発生前の状態まで復旧することで永続性を実現しています。
簡単に言うとトランザクション、今回でいうと送金処理が終
3. トランザクション処理の設計

トランザクション処理は、データベースの操作を安全かつ一貫性を保ちながら行うための非常に重要なプロセスになるので、Java言語ではトランザクション処理を設計するためにいくつかのクラスやインターフェイスを利用します。
Javaでのトランザクション処理の基本的な設計手法について説明いたします。
1.クラスとメソッドの準備
トランザクション処理を行う際には、まず関連するクラスとメソッドの準備が必要となります。
Javaにおけるトランザクションの管理は、主にデータベース接続を行うConnectionクラスを利用して行います。
Connectionクラスのインスタンスを取得し、適切なメソッドを用いてトランザクションを制御します。
トランザクション内で行った操作は、commitメソッドが呼ばれるまで実際のデータベースには反映されることはありません。
2.トランザクション処理の流れ
トランザクション処理の基本的な流れは、次の手順になります。
1. データベースへの接続を確立します。
2. トランザクションを開始するために、autoCommitモードをfalseに設定します。
3. 必要なデータベースの操作を行います。この段階ではデータベースに変更は反映されません。
4. 全ての操作が正常に完了した場合、commitメソッドを呼び出し、変更をデータベースに反映します。
5. 何らかのエラーが発生した場合は、rollbackメソッドを呼び出し、トランザクション開始前の状態に戻します。
以上のような流れでトランザクション処理が行われます。
Javaプログラム内でトランザクションを適切に管理することで、データベースの一貫性と安全性を保つことが可能となります。
4. まとめ
今回はトランザクション処理についてまとめてみました。
トランザクションは基幹システムやオンライン決済など今の生活になくてはならないシステムで導入されている非常に重要なシステムであることが分かりました。
次は実際にデータベースにアクセスしてトランザクション処理を実行する処理を作ってみようと思います。