トランザクション処理
トランザクションは、データベースに対する複数の更新を一つの処理として扱う単位です。もし複数の更新処理のうち、一つでも失敗したら更新前の状態に戻し、すべての更新処理が成功したら確定することができます。
Javaプログラムからデータベースを操作するときに、既定の設定では自動的確定するようになっているので、トランザクション処理をする場合はその機能をオフにする必要があります。その後、データベースに対する処理を行ない、成功したらコミット(確定)、失敗したらロールバック(取り消し)の指定をします。
トランザクション処理を行うにはConnectionオブジェクトを使います。トランザクション処理は次の手順で行います。
1. データベースに接続する
2. ConnectionオブジェクトのsetAutoCommitメソッドで自動コミット機能をオフにする
3. SQLコマンドを実行する
4. 確定(Commit)するか、取り消し(Rollback)をする
5. データベースを切断する
○ ファイル
StatementTest.javaファイルをコピーして、次のファイルを作成してください。
ファイル名 | TransactionTest.java |
---|
○ プログラム
次のようにプログラムを入力してください。
TransactionTest.java
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.Statement;
- public class TransactionTest{
- public static void main(String[] args){
- try{
- //JDBCドライバークラスを指定する
- String drivername = "com.mysql.cj.jdbc.Driver";
- //データベースを指定する
- String url = "jdbc:mysql://localhost:3306/books? characterEncoding=utf8";
- //ユーザー名を指定する
- String username = "root";
- //パスワードを指定する
- String password = "";
- //指定したドライバークラスを読み込む
- Class.forName(drivername);
- //データベースに接続する
- Connection con = DriverManager.getConnection(url, username, password);
- //自動コミットをオフにする
- con.setAutoCommit(false);
- //追加する情報を入力する
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- System.out.println("登録するユーザー情報を入力してください。");
- System.out.print("ID:");
- int id = Integer.parseInt(br.readLine());
- System.out.print("ユーザー名:");
- String uname = br.readLine();
- System.out.print("パスワード:");
- String passwd = br.readLine();
- System.out.print("氏名:");
- String name = br.readLine();
- //入力した情報をもとにSQL文を作成する
- String sql = "INSERT INTO Users VALUES(" + id + ", '" + uname + "', '" + passwd + "', '" + name + "')";
- //Statementオブジェクトを取得する
- Statement st = con.createStatement();
- //SQL文を実行する
- int ret = st.executeUpdate(sql);
- //変更のあった行数を表示する
- System.out.println("変更のあった件数:" + ret);
- //確定か取り消しを入力する
- System.out.print("1)確定 2)取り消し(デフォルト):");
- String input = br.readLine();
- switch(input){
- case "1":
- //確定
- con.commit();
- System.out.println("確定しました。");
- break;
- default:
- con.rollback();
- System.out.println("取り消しました。");
- break;
- }
- //データベースを切断する
- st.close();
- con.close();
- }catch(Exception e){
- //例外の状態を出力する
- e.printStackTrace();
- }
- }
- }
○ コンパイルと実行
C:¥work>javac TransactionTest.java
C:¥work>java -cp mysql-connector-java-8.0.22.jar;. TransactionTest
登録するユーザー情報を入力してください。
ID:5
ユーザー名:itou
パスワード:ipass
氏名:伊藤
変更のあった件数:1
1)確定 2)取り消し(デフォルト):2
取り消しました。
C:¥work>
○ 実行
C:¥work>java -cp mysql-connector-java-8.0.22.jar;. TransactionTest
登録するユーザー情報を入力してください。
ID:5
ユーザー名:itou
パスワード:ipass
氏名:伊藤
変更のあった件数:1
1)確定 2)取り消し(デフォルト):1
確定しました。
C:¥work>
○ 解説
29行目で、setAutoCommitメソッドの引数に「false」を指定することで、自動コミット機能をオフにしています。これにより、SQL文を実行するとトランザクションモードで実行され、すぐには確定されなくなります。
59行目から、確定するか、取り消すかの処理が行われます。もし確定する場合は62行目にあるように、Connectionオブジェクトのcommitメソッドを呼び出して確定します。これによりデータベース上の変更が確定され、データベースに反映されます。取り消す場合は66行目にあるようにConnectionオブジェクトのrollbackメソッドを呼び出して取り消します。これによりデータベース上の変更が破棄され、SQL文実行前の状態に戻ります。
今回は、SQL文実行後に確定するか、取り消すかの選択により、commitメソッド、rollbackメソッドを呼び出しましたが、ほかにも、複数のデータベース更新処理をtryブロックに記述し、その中で例外がスローされた場合に、その時点までのデータベース処理を取り消すために、catchブロックに取消処理を書くことができます。