JDBC操作事務
事務
事務的ACID
原子性:指事務是一個不可分割的單位,事務中的操作要麼都發生,要麼都不發生
一致性: 事務必須使數據庫從一個一致性狀態變換成另一個一致性狀態
隔離性: 一個事務的執行不能被其他事務干擾,各事務之間是隔離的
持久性: 一個事務一旦被提交,對數據庫中的數據的改變就是永久的
JDBC操作事務
可以使用JDBC來操作事務
conn.setAutoCommit(false); // 取消自動提交
conn.rollback(); //事務回滾
conn.commit(); //事務提交
SavePoint point = conn.setSavePoint(); // 設置事務保存點
conn.rollback(point); // 回滾到該保存點
數據庫隔離級別
如果沒有采取隔離機制的話,就會導致各種併發的數據問題
數據問題
- 髒讀: 對於兩個事務T1,T2,T1讀取了已經被T2更新但還沒有被提交的字段之後,若T2回滾,T1讀取到的內容就是臨時無效的
- 不可重複讀: 對於兩個事務T1,T2,T1讀取了一個字段,T2更新了該字段,之後T1再次讀取同一個字段,值就不同了
-
幻讀: 對於兩個事務T1,T2,T1從一個表中讀取了一個字段,然後T2在該表中插入了一些新的行,T1再次讀取同一個表,就會多出幾行
隔離級別越高,數據一致性越好,但是併發性越弱
數據庫的隔離級別
- READ UNCOMMITED(讀未提交的數據): 允許事務讀取未被其他事務提交的變更,髒讀、不可重複讀、幻讀問題都存在
- READ COMMITED(讀已提交的數據): 只允許事務讀取已被其他事務提交的數據,可以避免髒讀,但是不可重複讀和幻讀仍存在
- REPEATABLE READ(可重複讀): 確保事務可以多次從一個字段中讀取相同的值,在這個事務持續期間,禁止其他事務對這個字段進行更新,可以避免髒讀和不可重複讀,但幻讀仍存在(Mysql默認的事務隔離級別)
- SERIALIZABLE(串行化): 確保事務可以從一個表中讀取相同的行,在這個事務持續期間,禁止其他事務對該表執行插入、更新和刪除操作,所有併發問題都可以避免,但是性能低下
JDBC設置隔離級別
// <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>,
// <code>Connection.TRANSACTION_READ_COMMITTED</code>,
// <code>Connection.TRANSACTION_REPEATABLE_READ</code>
// <code>Connection.TRANSACTION_SERIALIZABLE</code>.
conn.setTransactionIsolation(int)
Mysql設置隔離級別
每個數據庫連接都有一個全局變量@@tx_isolation,表示當前的事務隔離級別
-- 查看當前會話的隔離級別 Mysql5.7.20之後為transaction_isolation
select @@tx_isolation;
-- 查看系統的隔離級別 MySql5.7.20之後transaction_isolation
select @@global.tx_isolation;
-- 設置當前連接的隔離級別
set session transaction isolation level read committed;
-- 設置數據庫系統的全局隔離級別
set global transaction isolation level read committed;