JDBC事務與保存點 JDBC簡介(七)


事務簡介

數據庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要么完全地執行,要么完全地不執行。
事務是必須滿足4個條件(ACID)
  • 事務的原子性( Atomicity)一組事務,要么全部成功;要么全部失敗。
  • 一致性 (Consistency):事務在完成時,必須使所有的數據都保持一致狀態。在相關數據庫中,所有規則都必須應用於事務的修改,以保持所有數據的完整性。比如一個學生表中新插入了一條記錄,這個學生的class_id必須是一個已經存在的正確的,A賬戶向B賬戶轉賬,不能出現負數,如果不做任何保障,出現了負數,這就是破壞了一致性可以認為是一致性表示數據本來是正確的,經過了事務,轉換為了另外的一個狀態,仍舊是正確的。
  • 隔離性(Isolation):由並發事務所作的修改必須與任何其它並發事務所作的修改隔離。也就是說另一並發事務要么讀取的是事務前的狀態,要么是事務后的狀態,不會是這個事務的中間狀態。
  • 持久性(Durability):事務完成之后,它對於系統的影響是永久性的。該修改即使出現致命的系統故障也將一直保持。
 
在默認情況下,MySQL每執行一條SQL語句,都是一個單獨的事務
如果需要將多條SQL語句設在在同一個事務中,那么需要開啟事務和結束事務
JDBC中與事務有關的方法
Connection與事務有關的主要方法:
  • setAutoCommit(boolean):設置是否為自動提交事務,如果true(默認值為true)表示自動提交,也就是每條執行的SQL語句都是一個單獨的事務;如果設置為false,那么相當於開啟了事務,con.setAutoCommit(false) 表示開啟事務。
  • commit():提交結束事務。
  • rollback():回滾結束事務。
  • setSavepoint():設置保存點。

事務使用示例

package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class MyTransactional {
public static void main(String[] args) throws Exception{
    String user = "root";
    String password = "123456";
    String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";
    //2、獲取連接對象
    Connection conn = DriverManager.getConnection(url, user, password);
    String sql = "delete from student where id='59'";
    //2、獲得sql語句執行對象
    Statement stmt = conn.createStatement();
    conn.setAutoCommit(false);
    //3、執行並保存結果集
    int rows = stmt.executeUpdate(sql);
    System.out.println("受影響的行: "+rows);
    conn.commit();
    // conn.rollback();
    conn.close();
    stmt.close();
}
}
在執行前開啟事務,conn.setAutoCommit(false);
注意:一定是執行前
只有開啟事務和結束事務之間的執行才屬於這個事務,如果像下面這樣,可以認為是兩個事務,前面一個自動提交了,然后開啟了新的事務,然后回滾了新的事務
 stmt.executeUpdate(sql); conn.setAutoCommit(false); conn.rollback();
最終通過commit或者rollback 結束事務。
通常的一個使用形式為:
try {
con = DBConnection.getConnection();
//開啟事務
con.setAutoCommit(false);

//處理業務邏輯

//提交事務
con.commit();
}
catch (SQLException e) {
e.printStackTrace();
//出現異常,回滾事務
try {
con.rollback();
System.out.println("JDBC Transaction rolled back successfully");
}
catch (SQLException e1) {
System.out.println("SQLException in rollback" + e.getMessage());
}
}

保存點

有的時候可能並不需要將一整個事務進行回滾,一個復雜的事務可能由幾個一致性的階段組成
保存點就是在一個事務中,插入幾個還原點,再出現問題時,可以及時的撤回到這個地方來
當撤回到一個還原點時,事務還在,仍在進行中,所以還需要再次的COMMIT,這次的COMMIT,保存點以下的執行相當於不存在。

 

package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Savepoint;
import java.sql.Statement;
public class MyTransactional {
public static void main(String[] args) throws Exception{
    String user = "root";
    String password = "123456";
    String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";
    //2、獲取連接對象
    Connection conn = DriverManager.getConnection(url, user, password);
    conn.setAutoCommit(false);
    String sql1 = "delete from student where id='158'";
    String sql2 = "delete from student where id='159'";
    //2、獲得sql語句執行對象
    Statement stmt = conn.createStatement();
    //3、執行並保存結果集
    stmt.executeUpdate(sql1);
    Savepoint savepoint1 = conn.setSavepoint("savepoint1");
    stmt.executeUpdate(sql2);
    Savepoint savepoint2 = conn.setSavepoint("savepoint2");
    conn.rollback(savepoint1);
    conn.commit();
    // conn.rollback();
    conn.close();
    stmt.close();
}
}
上面的示例中,執行了兩次刪除,刪除id=158時,創建保存點savepoint1;刪除id=159時,創建保存點savepoint2
將事務回滾到保存點1 conn.rollback(savepoint1);,然后進行提及,保存點savepoint1以上的部分成功提交,后面的部分沒有提交
也就是回滾到哪個保存點,那個保存點以下就相當於不存在
image_5c491b65_599e
保存點就是這樣將一整個完整的過程進行了拆分,rollback到哪個保存點,哪個保存點以下就會回滾,之前的就會提交
一定要注意: conn.rollback(savepoint1); 並不會結束事務,只有 conn.commit();或者 conn.rollback();方法才會結束事務。
image_5c491b65_3436


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM