JDBCトランザクションの例
JDBCトランザクションを使用すると、トランザクションをデータベースにコミットする方法とタイミングを制御できます。
….//transaction block start
単純なJDBCトランザクションでは、トランザクションブロック内のSQLステートメントのいずれかが失敗した場合、トランザクションブロック内のSQLステートメントがすべて正常に実行されたことを確認し、トランザクションブロック内のすべてを中断してロールバックします。 JDBCトランザクションの仕組みを理解するには、以下の2つの例を参照してください。 === 1. JDBCトランザクションなし デフォルトでは、 `executeUpdate()`が呼び出されるとデータはデータベースにコミットされます。
String insertTableSQL = “INSERT INTO DBUSER”
+ “(USER
ID, USERNAME, CREATED
BY, CREATED__DATE) VALUES”
+ “(?,?,?,?)”;
String updateTableSQL = “UPDATE DBUSER SET USERNAME =? ”
+ “WHERE USER__ID = ?”;
preparedStatementInsert = dbConnection.prepareStatement(insertTableSQL);
preparedStatementInsert.setInt(1, 999);
preparedStatementInsert.setString(2, “mkyong101”);
preparedStatementInsert.setString(3, “system”);
preparedStatementInsert.setTimestamp(4, getCurrentTimeStamp());
preparedStatementInsert.executeUpdate();//data COMMITTED into database.
preparedStatementUpdate = dbConnection.prepareStatement(updateTableSQL);
preparedStatementUpdate.setString(1, “A very very long string caused DATABASE ERROR”);
preparedStatementUpdate.setInt(2, 999);
preparedStatementUpdate.executeUpdate();//Error, value too big, ignore this update statement,
//but user__id=999 is inserted
このコードを実行すると、USER__ID = '999'が挿入されますが、ユーザー名は更新されません。 === 2. JDBCトランザクション これをトランザクションに入れるには、 . `dbConnection.setAutoCommit(false);`トランザクションブロックを開始します. . トランザクションブロックを終了するには `dbConnection.commit();`を実行します. コードスニペットを参照してください:
dbConnection.setAutoCommit(false);//transaction block start
String insertTableSQL = “INSERT INTO DBUSER”
+ “(USER
ID, USERNAME, CREATED
BY, CREATED__DATE) VALUES”
+ “(?,?,?,?)”;
String updateTableSQL = “UPDATE DBUSER SET USERNAME =? ”
+ “WHERE USER__ID = ?”;
preparedStatementInsert = dbConnection.prepareStatement(insertTableSQL);
preparedStatementInsert.setInt(1, 999);
preparedStatementInsert.setString(2, “mkyong101”);
preparedStatementInsert.setString(3, “system”);
preparedStatementInsert.setTimestamp(4, getCurrentTimeStamp());
preparedStatementInsert.executeUpdate();//data IS NOT commit yet
preparedStatementUpdate = dbConnection.prepareStatement(updateTableSQL);
preparedStatementUpdate.setString(1, “A very very long string caused DATABASE ERROR”);
preparedStatementUpdate.setInt(2, 999);
preparedStatementUpdate.executeUpdate();//Error, rollback, including the first insert statement.
dbConnection.commit();//transaction block end
このコードが実行されると、update文はヒットエラーとなり、insert文とupdate文の両方をロールバックします。 === 完全なJDBCトランザクションの例 完全なJDBCトランザクションの例を参照してください。
package com.mkyong.jdbc;
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCTransactionExample {
private static final String DB__DRIVER = "oracle.jdbc.driver.OracleDriver"; private static final String DB__CONNECTION = "jdbc:oracle:thin:@localhost:1521:MKYONG"; private static final String DB__USER = "user"; private static final String DB__PASSWORD = "password";
public static void main(String[]argv) throws SQLException {
Connection dbConnection = null; PreparedStatement preparedStatementInsert = null; PreparedStatement preparedStatementUpdate = null;
String insertTableSQL = "INSERT INTO DBUSER" + "(USER__ID, USERNAME, CREATED__BY, CREATED__DATE) VALUES" + "(?,?,?,?)";
String updateTableSQL = "UPDATE DBUSER SET USERNAME =? " + "WHERE USER__ID = ?";
try { dbConnection = getDBConnection();
dbConnection.setAutoCommit(false);
preparedStatementInsert = dbConnection.prepareStatement(insertTableSQL); preparedStatementInsert.setInt(1, 999); preparedStatementInsert.setString(2, "mkyong101"); preparedStatementInsert.setString(3, "system"); preparedStatementInsert.setTimestamp(4, getCurrentTimeStamp()); preparedStatementInsert.executeUpdate();
preparedStatementUpdate = dbConnection.prepareStatement(updateTableSQL); //preparedStatementUpdate.setString(1, //"A very very long string caused db error"); preparedStatementUpdate.setString(1, "new string"); preparedStatementUpdate.setInt(2, 999); preparedStatementUpdate.executeUpdate();
dbConnection.commit();
System.out.println("Done!");
} catch (SQLException e) {
System.out.println(e.getMessage()); dbConnection.rollback();
} finally {
if (preparedStatementInsert != null) { preparedStatementInsert.close(); }
if (preparedStatementUpdate != null) { preparedStatementUpdate.close(); }
if (dbConnection != null) { dbConnection.close(); }
}
}
private static Connection getDBConnection() {
Connection dbConnection = null;
try {
Class.forName(DB__DRIVER);
} catch (ClassNotFoundException e) {
System.out.println(e.getMessage());
}
try {
dbConnection = DriverManager.getConnection(DB__CONNECTION, DB__USER, DB__PASSWORD); return dbConnection;
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return dbConnection;
}
private static java.sql.Timestamp getCurrentTimeStamp() {
java.util.Date today = new java.util.Date(); return new java.sql.Timestamp(today.getTime());
}
}
link://tag/jdbc/[jdbc]link://タグ/トランザクション/[トランザクション]