中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中事務的特性有哪幾種

發布時間:2022-01-12 09:14:00 來源:億速云 閱讀:192 作者:iii 欄目:大數據

這篇“java中事務的特性有哪幾種”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“java中事務的特性有哪幾種”文章吧。

Java中事務的特性有四種,原子性、一致性、隔離性、持久性

原子性:如果執行一條sql,底層是默認執行事務的,叫做隱形事務,當執行多條sql語句的時候,多條sql語句不可以進行分割,必須全部一次性執行完成,就是要么全部完成,要么失敗;

一致性:事務完成后,數據狀態保持一致性,能量守恒定律,哈哈哈;

隔離性:多個事務并發訪問數據庫,事務對數據的修改,需要與其他事務進行隔離;

持久性:數據修改完成,數據持久化存儲;

使用JDBC,需要先關閉主動提交事務,然后執行多條SQL語句,然后提交,如果報錯進行回滾事務,在最后啟動自動提交,因為執行1條sql語句的時候,也會開啟事務,叫做隱形事務,默認進行提交,如果關閉了不啟動,以后執行一條SQL也需要顯示顯示事務了;

Connection conn = openConnection();
try {
    // 關閉自動提交:
    conn.setAutoCommit(false);// 執行多條SQL語句:insert(); update(); delete();// 提交事務:
    conn.commit();} catch (SQLException e) {
    // 回滾事務:
    conn.rollback();} finally {
    conn.setAutoCommit(true);conn.close();
}

Mysql隔離級別分為4種:Read Uncommitted(讀取未提交的)、Read Committed(讀取提交的)、Repeatable Red(可重復讀)、Serializaable(串行化)

Isolation Level臟讀(Dirty Read)不可重復讀(Non Repeatable Read)幻讀(Phantom Read)
Read UncommittedYesYesYes
Read Committed-YesYes
Repeatable Read--Yes
Serializable---

Read Uncommitted是隔離級別最低的一種事務級別。在這種隔離級別下,一個事務會讀到另一個事務更新后但未提交的數據,如果另一個事務回滾,那么當前事務讀到的數據就是臟數據,這就是臟讀(Dirty Read)。

mysql> select * from students;+----+-------+| id | name  |
+----+-------+|  1 | Alice |
+----+-------+1 row in set (0.00 sec)

然后,分別開啟兩個MySQL客戶端連接,按順序依次執行事務A和事務B:

當事務A執行完第3步時,它更新了id=1的記錄,但并未提交,而事務B在第4步讀取到的數據就是未提交的數據。

隨后,事務A在第5步進行了回滾,事務B再次讀取id=1的記錄,發現和上一次讀取到的數據不一致,這就是臟讀。

可見,在Read Uncommitted隔離級別下,一個事務可能讀取到另一個事務更新但未提交的數據,這個數據有可能是臟數據。

時刻事務A事務B
1SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
2BEGIN;BEGIN;
3UPDATE students SET name = 'Bob' WHERE id = 1; 
4 SELECT * FROM students WHERE id = 1;
5ROLLBACK; 
6 SELECT * FROM students WHERE id = 1;
7 COMMIT;

在Read Committed隔離級別下,一個事務可能會遇到不可重復讀(Non Repeatable Read)的問題。

不可重復讀是指,在一個事務內,多次讀同一數據,在這個事務還沒有結束時,如果另一個事務恰好修改了這個數據,那么,在第一個事務中,兩次讀取的數據就可能不一致。

我們仍然先準備好students表的數據:

mysql> select * from students;+----+-------+| id | name  |
+----+-------+|  1 | Alice |
+----+-------+1 row in set (0.00 sec)

然后,分別開啟兩個MySQL客戶端連接,按順序依次執行事務A和事務B:

當事務B第一次執行第3步的查詢時,得到的結果是Alice,隨后,由于事務A在第4步更新了這條記錄并提交,所以,事務B在第6步再次執行同樣的查詢時,得到的結果就變成了Bob,因此,在Read Committed隔離級別下,事務不可重復讀同一條記錄,因為很可能讀到的結果不一致。

時刻事務A事務B
1SET TRANSACTION ISOLATION LEVEL READ COMMITTED;SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
2BEGIN;BEGIN;
3 SELECT * FROM students WHERE id = 1;
4UPDATE students SET name = 'Bob' WHERE id = 1; 
5COMMIT; 
6 SELECT * FROM students WHERE id = 1;
7 COMMIT;

在Repeatable Read隔離級別下,一個事務可能會遇到幻讀(Phantom Read)的問題。

幻讀是指,在一個事務中,第一次查詢某條記錄,發現沒有,但是,當試圖更新這條不存在的記錄時,竟然能成功,并且,再次讀取同一條記錄,它就神奇地出現了。

我們仍然先準備好students表的數據:

mysql> select * from students;+----+-------+| id | name  |
+----+-------+|  1 | Alice |
+----+-------+1 row in set (0.00 sec)

然后,分別開啟兩個MySQL客戶端連接,按順序依次執行事務A和事務B:

事務B在第3步第一次讀取id=99的記錄時,讀到的記錄為空,說明不存在id=99的記錄。隨后,事務A在第4步插入了一條id=99的記錄并提交。事務B在第6步再次讀取id=99的記錄時,讀到的記錄仍然為空,但是,事務B在第7步試圖更新這條不存在的記錄時,竟然成功了,并且,事務B在第8步再次讀取id=99的記錄時,記錄出現了。

可見,幻讀就是沒有讀到的記錄,以為不存在,但其實是可以更新成功的,并且,更新成功后,再次讀取,就出現了。

時刻事務A事務B
1SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
2BEGIN;BEGIN;
3 SELECT * FROM students WHERE id = 99;
4INSERT INTO students (id, name) VALUES (99, 'Bob'); 
5COMMIT; 
6 SELECT * FROM students WHERE id = 99;
7 UPDATE students SET name = 'Alice' WHERE id = 99;
8 SELECT * FROM students WHERE id = 99;
9 COMMIT;

Serializable是最嚴格的隔離級別。在Serializable隔離級別下,所有事務按照次序依次執行,因此,臟讀、不可重復讀、幻讀都不會出現。

雖然Serializable隔離級別下的事務具有最高的安全性,但是,由于事務是串行執行,所以效率會大大下降,應用程序的性能會急劇降低。如果沒有特別重要的情景,一般都不會使用Serializable隔離級別。

默認隔離級別

如果沒有指定隔離級別,數據庫就會使用默認的隔離級別。在MySQL中,如果使用InnoDB,默認的隔離級別是Repeatable Read。

啟動事務

在啟動類上添加注解 @EnableTransactionManagement ,

在執行事務的方法上面使用 @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED)設置隔離界別與事務傳播。默認就是REQUIRED;

事務傳播

Spring的聲明式事務為事務傳播定義了幾個級別,默認傳播級別就是REQUIRED,它的意思是,如果當前沒有事務,就創建一個新事務,如果當前有事務,就加入到當前事務中執行。

SUPPORTS:表示如果有事務,就加入到當前事務,如果沒有,那也不開啟事務執行。這種傳播級別可用于查詢方法,因為SELECT語句既可以在事務內執行,也可以不需要事務;

MANDATORY:表示必須要存在當前事務并加入執行,否則將拋出異常。這種傳播級別可用于核心更新邏輯,比如用戶余額變更,它總是被其他事務方法調用,不能直接由非事務方法調用;

REQUIRES_NEW:表示不管當前有沒有事務,都必須開啟一個新的事務執行。如果當前已經有事務,那么當前事務會掛起,等新事務完成后,再恢復執行;

NOT_SUPPORTED:表示不支持事務,如果當前有事務,那么當前事務會掛起,等這個方法執行完成后,再恢復執行;

NEVER:和NOT_SUPPORTED相比,它不但不支持事務,而且在監測到當前有事務時,會拋出異常拒絕執行;

NESTED:表示如果當前有事務,則開啟一個嵌套級別事務,如果當前沒有事務,則開啟一個新事務。

以上就是關于“java中事務的特性有哪幾種”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

扶沟县| 新源县| 西藏| 通州市| 边坝县| 安岳县| 增城市| 安化县| 泰和县| 哈巴河县| 正蓝旗| 衡阳市| 白城市| 榆社县| 搜索| 安图县| 阿拉善右旗| 绥江县| 正定县| 吴川市| 唐海县| 静安区| 安义县| 四会市| 贵港市| 田东县| 江津市| 平果县| 新密市| 郑州市| 鄂托克前旗| 嵊州市| 冀州市| 曲松县| 惠东县| 赣州市| 元氏县| 小金县| 阳城县| 临湘市| 东宁县|