Guest User

Untitled

a guest
Oct 17th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.13 KB | None | 0 0
  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.PreparedStatement;
  4. import java.sql.SQLException;
  5. import java.util.List;
  6.  
  7. import transactionwithlocksample.dto.Item;
  8.  
  9. public class ItemDAO {
  10.  
  11. // 定数
  12. private final String CONNECTION_STR = "jdbc:oracle:thin:@172.16.4.2:1521:info";
  13. private final String DB_USERNAME = "ユーザー名";
  14. private final String DB_PASSWORD = "パスワード";
  15.  
  16. /**
  17. * 新規追加メソッド try with resources利用版(JDK v6以上)
  18. *  finallyでわざわざclose()しなくても自動的にclose()される。
  19. *  さらにcommit()されていない場合、自動的にrollback()される。 <= ウソ、コミットしてるわ
  20. *  なお、catch句を用意し、その中でcon.rollback()しても、
  21. *  catch句に入った時にはすでにcon.close()が実行されているため、
  22. *  ロールバックできない。 => だから、tryがネストする。なんかばっちいな
  23. */
  24. public int insert_v6(List<Item> list) throws SQLException
  25. {
  26. // 追加行数
  27. int result = 0;
  28.  
  29. try(
  30. Connection con =
  31. DriverManager.getConnection(CONNECTION_STR, DB_USERNAME, DB_PASSWORD);
  32. )
  33. {
  34. // AutoCommitを無効化
  35. con.setAutoCommit(false);
  36.  
  37. // 更新実行
  38. try(
  39. PreparedStatement pstmt =
  40. con.prepareStatement("INSERT INTO トランザクションテスト(id, 商品名, 価格) VALUES(?, ?, ?)");
  41. )
  42. {
  43. for(Item item : list)
  44. {
  45. // SQL中のパラメータマーカーに値をセット
  46. pstmt.setInt(1, item.getId());
  47. pstmt.setString(2, item.getName());
  48. pstmt.setInt(3, item.getPrice());
  49. // SQL実行
  50. // 戻り値はSQL実行によって影響を受けた行数
  51. // 新規追加なので、成功した場合は1
  52. result += pstmt.executeUpdate();
  53. }
  54.  
  55. // ここまで来れたら、トランザクション成功
  56. // commit実行
  57. con.commit();
  58. }catch(SQLException ex)
  59. {
  60. // 追加中に例外スロー
  61. // とりあえずロールバック
  62. // OracleはDB切断時に未コミットなデータがあればコミットする
  63. // よって、明示的にロールバック呼び出しが必要!!
  64. con.rollback();
  65.  
  66. // ここでは例外をつかってやることはないので、上位へスローしなおす
  67. throw ex;
  68. }
  69. }
  70.  
  71. // 更新された行数を返す
  72. return result;
  73. }
  74.  
  75.  
  76. /**
  77. * 更新メソッド 変更対象行をロックしてから更新
  78. *
  79. * @param list
  80. * @return
  81. * @throws SQLException
  82. */
  83. public int update(Item item) throws SQLException
  84. {
  85. // 変更行数
  86. int result = 0;
  87.  
  88. try(
  89. Connection con =
  90. DriverManager.getConnection(CONNECTION_STR, DB_USERNAME, DB_PASSWORD);
  91. )
  92. {
  93. // AutoCommitを無効化
  94. con.setAutoCommit(false);
  95.  
  96. // 変更対象をロックし、更新
  97. try(
  98. PreparedStatement pstmt4lock =
  99. con.prepareStatement("SELECT * FROM トランザクションテスト WHERE id=? for update");
  100. PreparedStatement pstmt4update =
  101. con.prepareStatement("UPDATE トランザクションテスト SET 価格=? WHERE id=?");
  102. )
  103. {
  104. // 変更対象行をロック
  105. // 先にロックされていたら、ロック解除待ち
  106. pstmt4lock.setInt(1, item.getId());
  107. if(pstmt4lock.execute())
  108. {
  109. // ロック成功
  110. // 更新実行
  111. // 戻り値はSQL実行によって影響を受けた行数
  112. // 更新対象行は主キーを条件にしているため、成功した場合は1
  113. pstmt4update.setInt(1, item.getPrice());
  114. pstmt4update.setInt(2, item.getId());
  115. result = pstmt4update.executeUpdate();
  116. }
  117.  
  118. // ここまで来れたら、トランザクション成功
  119. // commit実行
  120. con.commit();
  121. }
  122. catch(SQLException ex)
  123. {
  124. // 更新中に例外スロー
  125. // とりあえずロールバック
  126. // OracleはDB切断時に未コミットなデータがあればコミットする
  127. // よって、明示的にロールバック呼び出しが必要!!
  128. con.rollback();
  129.  
  130. // ここでは例外をつかってやることはないので、上位へスローしなおす
  131. throw ex;
  132. }
  133. }
  134.  
  135. // 更新された行数を返す
  136. return result;
  137. }
  138. }
Add Comment
Please, Sign In to add comment