1、事物屬性
事物屬性主要是通過TransactionDefinition接口實(shí)現(xiàn)定義,主要有事物的隔離級(jí)別竖独,事物的傳播性,事物的超時(shí)時(shí)間担扑,事物是否只讀
1)事物隔離級(jí)別:用來(lái)解決并發(fā)事物出現(xiàn)的問題,其使用TransactionDefinition中的靜態(tài)變量來(lái)指定:
?????????ISOLATION_DEFAULT:默認(rèn)隔離級(jí)別,即使用底層數(shù)據(jù)庫(kù)默認(rèn)的隔離級(jí)別;
? ? ? ? ?ISOLATION_READ_UNCOMMITTED:未提交讀烙丛;
? ? ? ? ?ISOLATION_READ_COMMITTED:提交讀,一般情況下我們使用這個(gè)羔味;
? ? ? ? ?ISOLATION_REPEATABLE_READ:可重復(fù)讀河咽;
? ? ? ? ?ISOLATION_SERIALIZABLE:序列化。
可以使用DefaultTransactionDefinition類中的setIsolationLevel方法來(lái)設(shè)計(jì)事物的隔離級(jí)別
2)事物傳播行為:spring管理的事物是邏輯事物介评,物理事物與邏輯事物兩者之間的區(qū)別就在于事物的傳播行為,事物的傳播行為指用于多個(gè)事物之間調(diào)用,事物是如何在這些方法間傳播的们陆,spring一共支持7中傳播行為:
userDao.save(user);??
?user.getAddress().setUserId(user.getId());??
?addressService.save(user.getAddress());
Required:必須有邏輯事物寒瓦,否則創(chuàng)建一個(gè)新事物PROPAGATION_REQUIRED指定,表示當(dāng)前如果有事物坪仇,則加入該事物杂腰,否則創(chuàng)建一個(gè)新事物
? ? 一.當(dāng)userService調(diào)用save()方法時(shí),此時(shí)spring用的required傳播行為并且spring事物管理器中沒有開啟邏輯事物椅文,所以spring管理器會(huì)開啟一個(gè)邏輯事物喂很;
? ? 二.當(dāng)addressService調(diào)用save()方法時(shí)發(fā)現(xiàn)同樣用的required傳播行為,因此使用已經(jīng)存在的邏輯事物
? ??三皆刺、在返回到addressService對(duì)象的save方法少辣,當(dāng)事務(wù)模板類執(zhí)行完畢,此時(shí)提交并關(guān)閉事務(wù)羡蛾。
?????? 因此userService對(duì)象的save方法和addressService的save方法屬于同一個(gè)物理事務(wù)漓帅,如果發(fā)生回滾,則兩者都回滾
RequiresNew:創(chuàng)建新的邏輯事務(wù)痴怨,使用PROPAGATION_REQUIRES_NEW指定忙干,表示每次都創(chuàng)建新的邏輯事務(wù)(物理事務(wù)也是不同的),如下圖:
該傳播行為執(zhí)行流程(正確提交情況):
一浪藻、當(dāng)執(zhí)行userService對(duì)象的save方法時(shí)捐迫,由于傳播行為是RequiresNew,因此創(chuàng)建一個(gè)新的邏輯事務(wù)(物理事務(wù)也是不同的)爱葵;
二施戴、當(dāng)執(zhí)行到addressService對(duì)象的save方法時(shí),由于傳播行為是RequiresNew钧惧,因此首先暫停上一個(gè)邏輯事務(wù)并創(chuàng)建一個(gè)新的邏輯事務(wù)(物理事務(wù)也是不同的);
三暇韧、addressService對(duì)象的save方法執(zhí)行完畢后,提交邏輯事務(wù)(并提交物理事務(wù))并重新恢復(fù)上一個(gè)邏輯事務(wù)浓瞪,繼續(xù)執(zhí)行userService對(duì)象的save方法內(nèi)的操作懈玻;
四、最后userService對(duì)象的save方法執(zhí)行完畢乾颁,提交邏輯事務(wù)(并提交物理事務(wù))涂乌;
五、userService對(duì)象的save方法和addressService對(duì)象的save方法不屬于同一個(gè)邏輯事務(wù)且也不屬于同一個(gè)物理事務(wù)英岭。
Supports:支持當(dāng)前事物湾盒,使用PROPAGATION_SUPPORTS指定,如果當(dāng)前存在邏輯事物诅妹,則加入當(dāng)前邏輯事物罚勾,如果沒有毅人,則以非事物方式提交
NotSupported:不支持事物,如果當(dāng)前存在事物則暫停該事物尖殃,使用PROPAGATION_NOT_SUPPORTED指定丈莺,以非事物方式執(zhí)行,如果當(dāng)前存在邏輯事務(wù)送丰,就把當(dāng)前事務(wù)暫停缔俄,以非事務(wù)方式執(zhí)行。
Mandatory:必須有事物器躏,否則拋出異常俐载,使用PROPAGATION_MANDATORY指定,使用當(dāng)前事物執(zhí)行登失,如果當(dāng)前沒有事物遏佣,則拋出異常。
Never:不支持事物壁畸,如果當(dāng)前有事物則拋出異常贼急,使用PROPAGATION_NEVER指定,即以非事物方式執(zhí)行捏萍,如果當(dāng)前存在事物太抓,則拋出異常。
Nested:嵌套事物支持令杈,使用PROPAGATION_NESTED指定走敌,如果當(dāng)前存在事物,則嵌套在事物內(nèi)執(zhí)行逗噩,如果當(dāng)前沒有事物掉丽,則創(chuàng)建一個(gè)新事物執(zhí)行,嵌套事物是以數(shù)據(jù)庫(kù)保存點(diǎn)來(lái)實(shí)現(xiàn)异雁,即嵌套事物回滾不會(huì)影響外部事物捶障,但外部事物回滾會(huì)影響嵌套事物。
Nested和RequiresNew的區(qū)別:
1.RequiredNew每次都是創(chuàng)建一個(gè)新的獨(dú)立的物理事物纲刀,而Nested只有一個(gè)物理事物
2.Nested嵌套事物發(fā)生回滾不會(huì)影響外部事物项炼,外部事物發(fā)生回滾會(huì)影響嵌套事物,而RequiredNew每次創(chuàng)建的都是新事物示绊,所以并沒有關(guān)聯(lián)锭部。
3.Nested使用JDBC 3的保存點(diǎn)實(shí)現(xiàn),即如果使用低版本驅(qū)動(dòng)將導(dǎo)致不支持嵌套事務(wù)面褐。
使用嵌套事務(wù)拌禾,必須確保具體事務(wù)管理器實(shí)現(xiàn)的nestedTransactionAllowed屬性為true,否則不支持嵌套事務(wù)展哭,如DataSourceTransactionManager默認(rèn)支持湃窍,而HibernateTransactionManager默認(rèn)不支持闻蛀,需要我們來(lái)開啟。