更新の途中でこけたら嫌だな。
こけても、ここまでは更新しときたいんだよな。
そんなあなた。
セーブポイントなら、自分の好きなところに戻せます。。
セーブポイントであ~る。
データベースなので、ロールバックはできないと困ります。
とは言え、すべての手順をロールバックされると困るときは、セーブポイントを使いましょう。
(ログとかおまけテーブルの更新はこけても良いから、本当に更新したい実績データだけでも担保したいときとかw)
Savepointクラスを使って、特定の位置までトランザクションをロールバックするサンプル
DUAL表のデータを2回更新したあと、1回目の更新後の状態に戻してコミットをします。
ちなみにDUAL表を更新してはいけません。良い子のみんなは真似しないでねw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Savepoint; public class SavePointOraTest { public static void main(String[] args) { try { new SavePointOraTest().execute(); }catch(Exception e) { e.printStackTrace(); } } public void execute() throws Exception { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; //おまじないw(ドライバのロード) Class.forName("oracle.jdbc.driver.OracleDriver"); //DBに接続(URL,USER_ID,PASSWORD) conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "SYS as SYSDBA", "MANAGER"); conn.setAutoCommit(false); try { //1.値を「X」から「Y」に変える pstmt = conn.prepareStatement("update dual set dummy = ? where dummy = ?"); pstmt.setString(1, "Y"); pstmt.setString(2, "X"); pstmt.executeUpdate(); //セーブポイントを作成 Savepoint sp = conn.setSavepoint("sp_test"); //2.値を「Y」から「Z」に変える pstmt = conn.prepareStatement("update dual set dummy = ? where dummy = ?"); pstmt.setString(1, "Z"); pstmt.setString(2, "Y"); pstmt.executeUpdate(); //値を「X」から「Y」に変えたあとまでロールバックして、コミット conn.rollback(sp); conn.commit(); } catch(SQLException sqle) { conn.rollback(); throw sqle; } //後始末 pstmt.close(); conn.close(); } } |
実行結果
2回目の更新がロールバックされて、1回目の更新までがDUAL表に反映(コミット)されます。
よって、値は「Y」になります。
サンプルの解説
セーブポイントの使い方は、簡単です。
戻したいポイントで、Connection#setSavepoint()をして、セーブしておきます。
今回はセーブポイントに名前(sp_test)をつけてみましたが、使わないので特に意味はないですw
ちなみに、名前を付けるのであれば、Oracleの場合、オブジェクト系なんでもそうですが、30byte以内でセーブポイントの名前を付けます。
あとは、Connection#rollback(SavePoint)で、戻したいセーブポイントを指定すれば、そこまでロールバックしてくれます。