こんにちは。「Javaを復習する初心者」です。
今回はデータベースのロールバックを使ってみました。
今回はトランザクションの制御として、ロールバックを使ってみました。トランザクションとは送信する複数のSQLを一つのグループとして扱う考え方ですが、今回はひとつのUPDATE文の発行をひとつのトランザクションとします。トランザクションの処理結果を確定させることをコミットといい、実行前の状態に戻すことをロールバックといいます。今回はロールバックを確認しました。
データベース側
使うデータベースはH2DataBaseです。データの用意に使ったCREATE文とINSERT文は以下です。前回と同じです。
データの用意
DROP TABLE IF EXISTS SAMPLE_USER;
CREATE TABLE SAMPLE_USER (
ID CHAR(10) not null primary key,
NAME VARCHAR(255) not null,
AGE INT not null,
YEAR INT not null
);
INSERT INTO SAMPLE_USER (ID, NAME, AGE, YEAR) VALUES('A000000001', 'サンプル名前1', 20, 1);
INSERT INTO SAMPLE_USER (ID, NAME, AGE, YEAR) VALUES('A000000002', 'サンプル名前2', 21, 2);
INSERT INTO SAMPLE_USER (ID, NAME, AGE, YEAR) VALUES('A000000003', 'サンプル名前3', 20, 1);
INSERT INTO SAMPLE_USER (ID, NAME, AGE, YEAR) VALUES('A000000004', 'サンプル名前4', 21, 2);
Java側でロールバック
さて、ロールバックの実験ですが、ロールバック前後の状態を確認するために、以下のメソッドを作りました。
一覧表示のメソッド
private static void select(Connection connection) {
try (PreparedStatement ps = connection.prepareStatement("SELECT * FROM SAMPLE_USER ORDER BY ID")) {
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("id") + ","
+ rs.getString("name") + ","
+ rs.getString("age") + ","
+ rs.getString("year"));
}
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
仮引数がConnectionクラスです。こうすることで接続中のデータベースに対して、SQLを発行するというメソッドを作ることができます。上記ではSAMPLE_USERテーブルのレコードをID順に表示するということをしています。順序を決める記述は、ORDER BY句です。
今回はmainメソッドの内容は以下です。
mainメソッドの内容
try (Connection connection = DriverManager.getConnection("jdbc:h2:~/test", "sa", "")) {
connection.setAutoCommit(false);
System.out.println("UPDATE前");
select(connection);
try (PreparedStatement ps = connection.prepareStatement("UPDATE SAMPLE_USER SET YEAR = ? WHERE ID = ?")) {
ps.setString(1, "99");
ps.setString(2, "A000000001");
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("UPDATE後");
select(connection);
connection.rollback();
System.out.println("ロールバック後");
select(connection);
} catch (Exception e) {
e.printStackTrace();
}
何も設定せずにUPDATE文を発行するとその時点でコミットされます。これはデフォルトの設定では、新しい接続は自動コミット・モードだからです。 これを解除するため、「connection.setAutoCommit(false);」を記述します。これでロールバックをすることが可能になります。
上記プログラムではひとつのUPDATE文を発行しています。IDがA000000001であるレコードのカラムYEARの値を更新しています。その前後で「select(connection);」を記述しています。SELECT文を発行して、コンソールにテーブルのレコードすべてを表示しています。
ロールバックを実行している個所は「connection.rollback();」です。この記述によって、ロールバックが実行されます。ロールバック後にテーブルのレコードすべてを表示しています。ロールバックでデータが元に戻ったのか確認するためです。
以下、実効結果です。
結果
UPDATE前
A000000001,サンプル名前1,20,1
A000000002,サンプル名前2,21,2
A000000003,サンプル名前3,20,1
A000000004,サンプル名前4,21,2
UPDATE後
A000000001,サンプル名前1,20,99
A000000002,サンプル名前2,21,2
A000000003,サンプル名前3,20,1
A000000004,サンプル名前4,21,2
ロールバック後
A000000001,サンプル名前1,20,1
A000000002,サンプル名前2,21,2
A000000003,サンプル名前3,20,1
A000000004,サンプル名前4,21,2
ロールバック後にA000000001のyearが1に戻っています。