開発者ドキュメント

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://タグ/トランザクション/[トランザクション]
モバイルバージョンを終了