Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- import java.util.List;
- import transactionwithlocksample.dto.Item;
- public class ItemDAO {
- // 定数
- private final String CONNECTION_STR = "jdbc:oracle:thin:@172.16.4.2:1521:info";
- private final String DB_USERNAME = "ユーザー名";
- private final String DB_PASSWORD = "パスワード";
- /**
- * 新規追加メソッド try with resources利用版(JDK v6以上)
- * finallyでわざわざclose()しなくても自動的にclose()される。
- * さらにcommit()されていない場合、自動的にrollback()される。 <= ウソ、コミットしてるわ
- * なお、catch句を用意し、その中でcon.rollback()しても、
- * catch句に入った時にはすでにcon.close()が実行されているため、
- * ロールバックできない。 => だから、tryがネストする。なんかばっちいな
- */
- public int insert_v6(List<Item> list) throws SQLException
- {
- // 追加行数
- int result = 0;
- try(
- Connection con =
- DriverManager.getConnection(CONNECTION_STR, DB_USERNAME, DB_PASSWORD);
- )
- {
- // AutoCommitを無効化
- con.setAutoCommit(false);
- // 更新実行
- try(
- PreparedStatement pstmt =
- con.prepareStatement("INSERT INTO トランザクションテスト(id, 商品名, 価格) VALUES(?, ?, ?)");
- )
- {
- for(Item item : list)
- {
- // SQL中のパラメータマーカーに値をセット
- pstmt.setInt(1, item.getId());
- pstmt.setString(2, item.getName());
- pstmt.setInt(3, item.getPrice());
- // SQL実行
- // 戻り値はSQL実行によって影響を受けた行数
- // 新規追加なので、成功した場合は1
- result += pstmt.executeUpdate();
- }
- // ここまで来れたら、トランザクション成功
- // commit実行
- con.commit();
- }catch(SQLException ex)
- {
- // 追加中に例外スロー
- // とりあえずロールバック
- // OracleはDB切断時に未コミットなデータがあればコミットする
- // よって、明示的にロールバック呼び出しが必要!!
- con.rollback();
- // ここでは例外をつかってやることはないので、上位へスローしなおす
- throw ex;
- }
- }
- // 更新された行数を返す
- return result;
- }
- /**
- * 更新メソッド 変更対象行をロックしてから更新
- *
- * @param list
- * @return
- * @throws SQLException
- */
- public int update(Item item) throws SQLException
- {
- // 変更行数
- int result = 0;
- try(
- Connection con =
- DriverManager.getConnection(CONNECTION_STR, DB_USERNAME, DB_PASSWORD);
- )
- {
- // AutoCommitを無効化
- con.setAutoCommit(false);
- // 変更対象をロックし、更新
- try(
- PreparedStatement pstmt4lock =
- con.prepareStatement("SELECT * FROM トランザクションテスト WHERE id=? for update");
- PreparedStatement pstmt4update =
- con.prepareStatement("UPDATE トランザクションテスト SET 価格=? WHERE id=?");
- )
- {
- // 変更対象行をロック
- // 先にロックされていたら、ロック解除待ち
- pstmt4lock.setInt(1, item.getId());
- if(pstmt4lock.execute())
- {
- // ロック成功
- // 更新実行
- // 戻り値はSQL実行によって影響を受けた行数
- // 更新対象行は主キーを条件にしているため、成功した場合は1
- pstmt4update.setInt(1, item.getPrice());
- pstmt4update.setInt(2, item.getId());
- result = pstmt4update.executeUpdate();
- }
- // ここまで来れたら、トランザクション成功
- // commit実行
- con.commit();
- }
- catch(SQLException ex)
- {
- // 更新中に例外スロー
- // とりあえずロールバック
- // OracleはDB切断時に未コミットなデータがあればコミットする
- // よって、明示的にロールバック呼び出しが必要!!
- con.rollback();
- // ここでは例外をつかってやることはないので、上位へスローしなおす
- throw ex;
- }
- }
- // 更新された行数を返す
- return result;
- }
- }
Add Comment
Please, Sign In to add comment