資料庫的事務及實現CRUD功能
阿新 • • 發佈:2021-02-01
一、概念
一組邏輯操作單元(一個或多個DML操作),使資料從一種狀態變換到另一種狀態。
二、事務的屬性(ACID)
1.原子性(Atomicity)
原子性是指事務是一個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生。
2.一致性(Consistency)
事務必須使資料庫從一個一致性狀態變換到另一個一致性狀態。
3.隔離性(Isolation)
事務的隔離性是指一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的資料對併發的其他事務是隔離的,併發執行的各個事務之間不能互相干擾。
2.1 資料庫的併發問題
資料操作過程中可能出現的問題:(針對隔離性)
- 髒讀
對於兩個事務 T1, T2, T1 讀取了已經被 T2 更新但還沒有被提交的欄位。之後, 若 T2 回滾, T1讀取的內容就是臨時且無效的。 - 不可重複讀
對於兩個事務T1, T2, T1 讀取了一個欄位, 然後 T2 更新了該欄位。之後, T1再次讀取同一個欄位, 值就不同了。 - 幻讀
對於兩個事務T1, T2, T1 從一個表中讀取了一個欄位, 然後 T2 在該表中插入了一些新的行。之後, 如果 T1 再次讀取同一個表, 就會多出幾行。
2.2 四種隔離級別
- mysql預設REPEATABLE READ
二、事務處理原則
保證所事務都作為一個工作單元來執行,即使出現了故障,都不能改變這種執行方式。當在一個事務中執行多個操作時,要麼所有的事務都被提交(commit)
三、說明
1.資料一旦提交,就不可回滾
2.哪些操作會導致資料的自動提交?
- DDL操作一旦執行,都會自動提交。
set autocommit = false 對DDL操作失效 - DML預設情況下,一旦執行,就會自動提交。
我們可以通過set autocommit = false的方式取消DML操作的自動提交。 - 預設在關閉連線時,會自動的提交資料
四、程式碼體現
1.獲取資料庫的連線
Connection conn = JDBCUtils.getConnection();== //方式1:手動獲取連線 方式2:資料庫連線池==
conn.setAutoCommit(false); //體現事務
2.如下的多個DML操作,作為一個事務出現:
操作1:需要使用通用的增刪改查操作
//通用的增刪改查操作如何實現?//方式1:手動使用PreparedStatement實現;//方式2:使用dbutils.jar中QueryRunner類
操作2:需要使用通用的增刪改查操作
操作3:需要使用通用的增刪改查操作
conn.commit();
3.如果出現異常
conn.rollback();
4.關閉資源
JDBCUtils.closeResource(…,…,…); //方式1:手動關閉資源 方式2:DbUtils類的關閉方法
@Test
public void testUpdateWithTx() {
Connection conn = null;
try {
conn = JDBCUtils.getConnection();
System.out.println(conn.getAutoCommit());//true
//1.取消資料的自動提交
conn.setAutoCommit(false);
String sql1 = "update user_table set balance = balance - 100 where user = ?";
update(conn,sql1, "AA");
//模擬網路異常
System.out.println(10 / 0);
String sql2 = "update user_table set balance = balance + 100 where user = ?";
update(conn,sql2, "BB");
System.out.println("轉賬成功");
//2.提交資料
conn.commit();
} catch (Exception e) {
e.printStackTrace();
//3.回滾資料
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
//修改其為自動提交資料
//主要針對於使用資料庫連線池的使用
try {
conn.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
JDBCUtils.closeResource(conn, null);
}
}