注目記事

【Javaコード入門】データベース_⑤setAutoCommit/commit/rollbackメソッド

トランザクションを利用する – setAutoCommit/commit/rollbackメソッド

public void setAutoCommit(boolean auto) throws SQLException
public void commit() throws SQLException
public void rollback() throws SQLException
 auto:自動コミットを有効にするか

トランザクションとは、データベースに対する複数の処理をまとめるためのしくみを言います。たとえば銀行での振り込み処理であれば、

  • 振り込み元口座の残高を減らす
  • 振り込み先口座の残高を増やす

という処理はいずれも成功するか、または失敗しなければなりません。いずれかの処理だけが成功した場合、口座間の残高が正しくなくなってしまうからです。
そのような場合、トランザクションを利用することで、複数の更新をいったん仮登録しておき、すべての処理が成功したところで、データベースに本登録します(これをコミットと言います)。もしもいずれかが失敗した場合には、先行する仮登録をキャンセルします(これをロールバックと言います)。
これによって、双方の処理がいずれも成功、さもなければいずれも失敗することを保証しているわけです。 これまでは、ひとつの命令を実行する度に暗黙的にコミットしていましたので(これを自動コミットと言います)、トランザクションを意識することはありませんでした。しかし、複数の命令をトランザクションで管理したいという場合には、自動コミットを無効化する必要があります。これには、setAutoCommitメソッドにfalseをセットしてください。
自動コミットを無効にした場合、更新内容をデータベースに反映させるためには、明示的にcommitメソッドを呼び出さなければなりません。また、変更をキャンセルするには、rollbackメソッドを呼び出してください。

SqlTransact.java
  1. package com.example.mynavi.sql;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.DriverManager;
  5. import java.sql.SQLException;
  6.  
  7. public class SqlTransact {
  8.   public static void main(String[] args) {
  9.     try (var db = DriverManager.getConnection("jdbc:mysql:⁄⁄localhost/sample", "root", "12345")) {
  10.       db.setAutoCommit(false);
  11.       try(var ps1 = db.prepareStatement(
  12.           "INSERT INTO members (id, nam, sex, age) VALUES (?, ?, ?, ?)");
  13.         var ps2 = db.prepareStatement(
  14.           "INSERT INTO members (id, nam, sex, age) VALUES (?, ?, ?, ?)");) {
  15.         ps1.setString(1, "2016003");
  16.         ps1.setString(2, "田中春香");
  17.         ps1.setString(3, "女");
  18.         ps1.setInt(4, 28);
  19.         ps1.executeUpdate();
  20.         ps2.setString(1, "2016003");
  21.         ps2.setString(2, "和田和也");
  22.         ps2.setString(3, "男");
  23.         ps2.setInt(4, 34);
  24.         ps2.executeUpdate();
  25.         db.commit();
  26.       } catch (SQLException e) {
  27.         db.rollback();
  28.         System.out.println("処理エラー:" + e.getMessage());
  29.       }
  30.     } catch (Exception e) {
  31.       e.printStackTrace();
  32.     }
  33.   }
  34. }

  1. 処理エラー:Duplicate entry '2016003' for key 'members.PRIMARY'

上の例であれば、主キーが重複しているため、2番目のINSERT命令が失敗し(=ロールバックされ)、データの変更は反映されないはずです。太字部分の主キーを変更し、再度実行すると、今度は正しくデータが反映されることも確認してください。

データベース_目次
データベースの準備
データベースに接続/切断する
prepareStatement/executeUpdateメソッド
executeQueryメソッド
setAutoCommit/commit/rollbackメソッド
``