情報処理とは何から、データベースの基本的な話(情報処理試験のデータベーススペシャリスト程度の話まで)を書く、土日のシリーズ「Hello World程度のデータベース」です。
いままで、三層スキーマ構造により、データベースを説明してきた後に、データベースと、外部プログラムとのつなぎ部分として、データベースのデーモンとJDBCについて説明しました。
で、前回説明したJDBCのやりかたは、Selectの場合や、テーブルが1つの場合は、それでいいのですが、テーブルが2つ以上を更新する際、そのテーブル間に関連があると問題があります。今回は、その問題と、解決法としてのトランザクションの話、そして、それをJDBCで実現する方法です。
■テーブルが2つ以上の時、関連があるものを更新する場合の問題
たとえば、受注テーブルと、受注明細テーブルがあったとき、
受注テーブルだけ追加して、受注明細テーブルを追加しないと、受注があったことはわかるけど、中身がない(中身は普通受注明細に書かれる)のでわかんなーい(>_<!)となります。
受注明細だけ更新されても、誰が注文を出したのか(というのは、普通受注テーブルに書かれる)わかんなーい(>_<!)ってことになります。
受注テーブルを更新したら、必ず受注明細テーブルを更新し、
受注テーブルの更新に失敗したら、必ず受注明細テーブルも更新しない
というように2つ同期をとって更新してくれないと困ります。
ちなみに、そんなことはあるのかというと、受注テーブルを更新したあと、ディスクがいっぱいになった、受注明細テーブルを誰かが更新していて、ロックを解除しなかったため、タイムアウトになってしまった。。。など、ありえないことではありません。
■トランザクション処理
そこで、2つ以上のテーブル処理を行う場合、トランザクション処理というのがあります。
トランザクションをスタートして
全部正常に更新できたら、「コミット」をします。そうすると、更新されます。
逆に、「ロールバック」すると、トランザクションをスタートされた前にもどします
=今まで更新したものは、なかったものにされます。
このようにして、トランザクション処理を行うと、複数テーブルでも、全部更新するか、まったくしないか、どっちかにできて、矛盾なく処理できます。
なお、いままでのように1つのテーブルしか処理しない場合、トランザクションは意識しなくてもいいっていえばいいわけです、
そのようなために、データベースでは、自動コミットモードというのがあって、その場合には、こちらで指定しなくても、DBのほうで、テキトーなところで、コミットしてくれます。
MySQLでは、デフォルトでは、自動コミットモードになります。
■JDBCでのトランザクション処理
では、実際にJDBCで、トランザクション処理をする場合は、どうするか?というと、
こんなかんじ
http://www.hellohiro.com/jdbctransaction.htm
で行います(と、JavaでHelloWorldの内容を引用してしまう ^^;)
つまり、以下のとおり
・ドライバクラスをロードするところは同じ
・データベースへ接続するところもおなじ
・自動コミットモードを解除します
・ステートメントオブジェクトを生成するのも同じ
・実行するときは、addBatchを発行して、executeBatchで実行します
・成功時は、commit、エラー時は、rollbackします
・クローズ処理します。
(赤字は、トランザクション処理で追加になった処理です)
ってなかんじで、トランザクション処理はおしまい