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
package com.example.mynavi.sql; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class SqlTransact { public static void main(String[] args) { try (Connection db = DriverManager.getConnection( "jdbc:mysql:⁄⁄localhost/sample?serverTimezone=JST&useUnicode=true&characterEncoding=UTF-8&useSSL=true", "root", "12345")) { db.setAutoCommit(false); try(PreparedStatement ps1 = db.prepareStatement( "INSERT INTO members (id, nam, sex, age) VALUES (?, ?, ?, ?)"); PreparedStatement ps2 = db.prepareStatement( "INSERT INTO members (id, nam, sex, age) VALUES (?, ?, ?, ?)");) { ps1.setString(1, "2016003"); ps1.setString(2, "田中春香"); ps1.setString(3, "女"); ps1.setInt(4, 28); ps1.executeUpdate(); ps2.setString(1, "2016003"); ps2.setString(2, "和田和也"); ps2.setString(3, "男"); ps2.setInt(4, 34); ps2.executeUpdate(); db.commit(); } catch (SQLException e) { db.rollback(); System.out.println("処理エラー:" + e.getMessage()); } } catch (Exception e) { e.printStackTrace(); } } }
処理エラー:Duplicate entry '2016003' for key 'PRIMARY'
上の例であれば、主キーが重複しているため、2番目のINSERT命令が失敗し(=ロールバックされ)、データの変更は反映されないはずです。太字部分の主キーを変更し、再度実行すると、今度は正しくデータが反映されることも確認してください。