溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java中事務(wù)的特性有哪幾種

發(fā)布時(shí)間:2022-01-12 09:14:00 來(lái)源:億速云 閱讀:190 作者:iii 欄目:大數(shù)據(jù)

這篇“java中事務(wù)的特性有哪幾種”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“java中事務(wù)的特性有哪幾種”文章吧。

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

原子性:如果執(zhí)行一條sql,底層是默認(rèn)執(zhí)行事務(wù)的,叫做隱形事務(wù),當(dāng)執(zhí)行多條sql語(yǔ)句的時(shí)候,多條sql語(yǔ)句不可以進(jìn)行分割,必須全部一次性執(zhí)行完成,就是要么全部完成,要么失??;

一致性:事務(wù)完成后,數(shù)據(jù)狀態(tài)保持一致性,能量守恒定律,哈哈哈;

隔離性:多個(gè)事務(wù)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù),事務(wù)對(duì)數(shù)據(jù)的修改,需要與其他事務(wù)進(jìn)行隔離;

持久性:數(shù)據(jù)修改完成,數(shù)據(jù)持久化存儲(chǔ);

使用JDBC,需要先關(guān)閉主動(dòng)提交事務(wù),然后執(zhí)行多條SQL語(yǔ)句,然后提交,如果報(bào)錯(cuò)進(jìn)行回滾事務(wù),在最后啟動(dòng)自動(dòng)提交,因?yàn)閳?zhí)行1條sql語(yǔ)句的時(shí)候,也會(huì)開(kāi)啟事務(wù),叫做隱形事務(wù),默認(rèn)進(jìn)行提交,如果關(guān)閉了不啟動(dòng),以后執(zhí)行一條SQL也需要顯示顯示事務(wù)了;

Connection conn = openConnection();
try {
    // 關(guān)閉自動(dòng)提交:
    conn.setAutoCommit(false);// 執(zhí)行多條SQL語(yǔ)句:insert(); update(); delete();// 提交事務(wù):
    conn.commit();} catch (SQLException e) {
    // 回滾事務(wù):
    conn.rollback();} finally {
    conn.setAutoCommit(true);conn.close();
}

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

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

Read Uncommitted是隔離級(jí)別最低的一種事務(wù)級(jí)別。在這種隔離級(jí)別下,一個(gè)事務(wù)會(huì)讀到另一個(gè)事務(wù)更新后但未提交的數(shù)據(jù),如果另一個(gè)事務(wù)回滾,那么當(dāng)前事務(wù)讀到的數(shù)據(jù)就是臟數(shù)據(jù),這就是臟讀(Dirty Read)。

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

然后,分別開(kāi)啟兩個(gè)MySQL客戶端連接,按順序依次執(zhí)行事務(wù)A和事務(wù)B:

當(dāng)事務(wù)A執(zhí)行完第3步時(shí),它更新了id=1的記錄,但并未提交,而事務(wù)B在第4步讀取到的數(shù)據(jù)就是未提交的數(shù)據(jù)。

隨后,事務(wù)A在第5步進(jìn)行了回滾,事務(wù)B再次讀取id=1的記錄,發(fā)現(xiàn)和上一次讀取到的數(shù)據(jù)不一致,這就是臟讀。

可見(jiàn),在Read Uncommitted隔離級(jí)別下,一個(gè)事務(wù)可能讀取到另一個(gè)事務(wù)更新但未提交的數(shù)據(jù),這個(gè)數(shù)據(jù)有可能是臟數(shù)據(jù)。

時(shí)刻事務(wù)A事務(wù)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隔離級(jí)別下,一個(gè)事務(wù)可能會(huì)遇到不可重復(fù)讀(Non Repeatable Read)的問(wèn)題。

不可重復(fù)讀是指,在一個(gè)事務(wù)內(nèi),多次讀同一數(shù)據(jù),在這個(gè)事務(wù)還沒(méi)有結(jié)束時(shí),如果另一個(gè)事務(wù)恰好修改了這個(gè)數(shù)據(jù),那么,在第一個(gè)事務(wù)中,兩次讀取的數(shù)據(jù)就可能不一致。

我們?nèi)匀幌葴?zhǔn)備好students表的數(shù)據(jù):

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

然后,分別開(kāi)啟兩個(gè)MySQL客戶端連接,按順序依次執(zhí)行事務(wù)A和事務(wù)B:

當(dāng)事務(wù)B第一次執(zhí)行第3步的查詢時(shí),得到的結(jié)果是Alice,隨后,由于事務(wù)A在第4步更新了這條記錄并提交,所以,事務(wù)B在第6步再次執(zhí)行同樣的查詢時(shí),得到的結(jié)果就變成了Bob,因此,在Read Committed隔離級(jí)別下,事務(wù)不可重復(fù)讀同一條記錄,因?yàn)楹芸赡茏x到的結(jié)果不一致。

時(shí)刻事務(wù)A事務(wù)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隔離級(jí)別下,一個(gè)事務(wù)可能會(huì)遇到幻讀(Phantom Read)的問(wèn)題。

幻讀是指,在一個(gè)事務(wù)中,第一次查詢某條記錄,發(fā)現(xiàn)沒(méi)有,但是,當(dāng)試圖更新這條不存在的記錄時(shí),竟然能成功,并且,再次讀取同一條記錄,它就神奇地出現(xiàn)了。

我們?nèi)匀幌葴?zhǔn)備好students表的數(shù)據(jù):

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

然后,分別開(kāi)啟兩個(gè)MySQL客戶端連接,按順序依次執(zhí)行事務(wù)A和事務(wù)B:

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

可見(jiàn),幻讀就是沒(méi)有讀到的記錄,以為不存在,但其實(shí)是可以更新成功的,并且,更新成功后,再次讀取,就出現(xiàn)了。

時(shí)刻事務(wù)A事務(wù)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是最嚴(yán)格的隔離級(jí)別。在Serializable隔離級(jí)別下,所有事務(wù)按照次序依次執(zhí)行,因此,臟讀、不可重復(fù)讀、幻讀都不會(huì)出現(xiàn)。

雖然Serializable隔離級(jí)別下的事務(wù)具有最高的安全性,但是,由于事務(wù)是串行執(zhí)行,所以效率會(huì)大大下降,應(yīng)用程序的性能會(huì)急劇降低。如果沒(méi)有特別重要的情景,一般都不會(huì)使用Serializable隔離級(jí)別。

默認(rèn)隔離級(jí)別

如果沒(méi)有指定隔離級(jí)別,數(shù)據(jù)庫(kù)就會(huì)使用默認(rèn)的隔離級(jí)別。在MySQL中,如果使用InnoDB,默認(rèn)的隔離級(jí)別是Repeatable Read。

啟動(dòng)事務(wù)

在啟動(dòng)類上添加注解 @EnableTransactionManagement ,

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

事務(wù)傳播

Spring的聲明式事務(wù)為事務(wù)傳播定義了幾個(gè)級(jí)別,默認(rèn)傳播級(jí)別就是REQUIRED,它的意思是,如果當(dāng)前沒(méi)有事務(wù),就創(chuàng)建一個(gè)新事務(wù),如果當(dāng)前有事務(wù),就加入到當(dāng)前事務(wù)中執(zhí)行。

SUPPORTS:表示如果有事務(wù),就加入到當(dāng)前事務(wù),如果沒(méi)有,那也不開(kāi)啟事務(wù)執(zhí)行。這種傳播級(jí)別可用于查詢方法,因?yàn)镾ELECT語(yǔ)句既可以在事務(wù)內(nèi)執(zhí)行,也可以不需要事務(wù);

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

REQUIRES_NEW:表示不管當(dāng)前有沒(méi)有事務(wù),都必須開(kāi)啟一個(gè)新的事務(wù)執(zhí)行。如果當(dāng)前已經(jīng)有事務(wù),那么當(dāng)前事務(wù)會(huì)掛起,等新事務(wù)完成后,再恢復(fù)執(zhí)行;

NOT_SUPPORTED:表示不支持事務(wù),如果當(dāng)前有事務(wù),那么當(dāng)前事務(wù)會(huì)掛起,等這個(gè)方法執(zhí)行完成后,再恢復(fù)執(zhí)行;

NEVER:和NOT_SUPPORTED相比,它不但不支持事務(wù),而且在監(jiān)測(cè)到當(dāng)前有事務(wù)時(shí),會(huì)拋出異常拒絕執(zhí)行;

NESTED:表示如果當(dāng)前有事務(wù),則開(kāi)啟一個(gè)嵌套級(jí)別事務(wù),如果當(dāng)前沒(méi)有事務(wù),則開(kāi)啟一個(gè)新事務(wù)。

以上就是關(guān)于“java中事務(wù)的特性有哪幾種”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI