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";
    //二、獲取鏈接對象
    Connection conn = DriverManager.getConnection(url, user, password);
    String sql = "delete from student where id='59'";
    //二、得到sql語句執行對象
    Statement stmt = conn.createStatement();
    conn.setAutoCommit(false);
    //三、執行並保存結果集
    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";
    //二、獲取鏈接對象
    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'";
    //二、得到sql語句執行對象
    Statement stmt = conn.createStatement();
    //三、執行並保存結果集
    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
相關文章
相關標籤/搜索