user表數據html
user1表數據java
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
connection = DriverManager.getConnection(url,"root","root");
// 禁止jdbc自動提交事務
//connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement("update user set money = money-? where id= ?");
preparedStatement.setInt(1,10);
preparedStatement.setInt(2,1);
preparedStatement.executeUpdate();
//拋出異常
String str = null;
if(str.equals("")){
}
preparedStatement = connection.prepareStatement("update user1 set money = money+? where id = ?");
preparedStatement.setInt(1,10);
preparedStatement.setInt(2,1);
preparedStatement.executeUpdate();
// 提交事務
//connection.commit();
} catch (Exception e) {
e.printStackTrace();
// 回滾事務
// try {
// connection.rollback();
//} catch (SQLException e1) {
// e1.printStackTrace();
//}
}finally {
try {
preparedStatement.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
複製代碼
由上述代碼可知:操做一執行成功後,代碼出現異常,致使操做二沒法進行 但轉帳過程是一個事務:操做應要麼所有成功,要麼所有失敗mysql
所以咱們應該:
一、禁止jdbc自動提交事務
connection.setAutoCommit(false);
二、在兩條SQl語句執行完以後提交事務
connection.commit();
三、若是有異常則回滾事務
catch (Exception e) {
e.printStackTrace();
// 回滾事務
try {
connection.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
複製代碼
關於事務提交、回滾的理解:sql
事務的原子性數據庫
<數據庫事務不可分割的單位,要麼都作,要麼都不作>
事務是最小單元,不可再分,要麼所有執行成功,要麼所有失敗回滾。
複製代碼
事務的一致性markdown
<事務的操做不會改變數據庫的狀態,比方說惟一約束>
一致性是指事務必須使數據庫從一個一致的狀態變到另一個一致的狀態,
也就是執行事務以前和以後的狀態都必須處於一致 的狀態。
不一致性包含三點:髒讀,不可重複讀,幻讀
複製代碼
事務的隔離性併發
<事務是相互不可見的>
隔離性是指當多個用戶併發訪問數據庫時,好比操做同一張表時,數據庫爲每個用戶開啓的事務,不能被其餘事務的操做所 干擾,多個併發事務之間要相互隔離
複製代碼
事務的持久性oop
<事務一旦提交,即便宕機也是能恢復的>
DBMS(數據庫管理系統)對數據的修改是永久性的。
複製代碼
www.cnblogs.com/wyaokai/p/1…優化
mysql默認的事務隔離級別爲repeatable-read
未提交讀
讀未提交,即可以讀取到沒有被提交的數據
因此很明顯這個級別的隔離機制沒法解決髒讀、不可重複讀、幻讀中的任何一種。
複製代碼
已提交讀
讀已提交,即可以讀到那些已經提交的數據
天然可以防止髒讀,可是沒法限制不可重複讀和幻讀
複製代碼
可重複讀
可重複讀,讀取了一條數據,這個事務不結束,
別的事務就不能夠改這條記錄,這樣就解決了髒讀、不可重複讀的問題,
複製代碼
串行化
串行化,多個事務時,只有運行完一個事務以後,才能運行其餘事務。
複製代碼
補充:
一、事務隔離級別爲讀提交時,寫數據只會鎖住相應的行
二、事務隔離級別爲可重複讀時,若是檢索條件有索引(包括主鍵索引)的時候,默認加鎖方式是next-key 鎖;若是檢索條件沒有索引,更新數據時會鎖住整張表。一個間隙被事務加了鎖,其餘事務是不能在這個間隙插入記錄的,這樣能夠防止幻讀。
三、事務隔離級別爲串行化時,讀寫數據都會鎖住整張表
四、隔離級別越高,越能保證數據的完整性和一致性,可是對併發性能的影響也越大。
五、MYSQL MVCC實現機制參考連接:blog.csdn.net/whoamiyang/…
六、關於next-key 鎖能夠參考連接:blog.csdn.net/bigtree_372…
一、髒讀:事務A讀取了事務B更新的數據,而後B回滾操做,那麼A讀取到的數據是髒數據
二、不可重複讀:事務 A 屢次讀取同一數據,事務 B 在事務A屢次讀取的過程當中,對數據做了更新並提交,致使事務A屢次讀取同一數據時,結果 不一致。
三、幻讀:系統管理員A將數據庫中全部學生的成績從具體分數改成ABCDE等級,可是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺同樣,這就叫幻讀。 小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住知足條件的行,解決幻讀須要鎖表
<輕量級鎖,鎖的時間很是短,用來鎖臨界資源>