欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring事務(wù)@Transactional失效原因及解決辦法小結(jié)

 更新時(shí)間:2023年08月20日 10:47:23   作者:程序猿(攻城獅)  
今天就跟大家聊聊有關(guān)spring中@Transactional失效原因及解決辦法小結(jié),主要從三個(gè)方面考慮,具有一定的參考價(jià)值,感興趣的可以了解一下

spring事務(wù)@Transactional失效情況分析主要從以下幾個(gè)方面考慮:

1. mysql數(shù)據(jù)庫(kù)

默認(rèn)情況下mysql數(shù)據(jù)庫(kù)使用的是Innodb存儲(chǔ)引擎(5.5版本之后),它是支持事務(wù)的,但是如果你的表的存儲(chǔ)引擎是MyISAM,MyISAM是不支持事務(wù)的。這樣就會(huì)出現(xiàn)“事務(wù)失效”的問(wèn)題了。

解決方案:修改存儲(chǔ)引擎為Innodb。

2. 業(yè)務(wù)代碼

2.1 執(zhí)行事務(wù)的Bean交由Spring管理

我們要使用Spring的申明式事務(wù),那么需要執(zhí)行事務(wù)的Bean是否已經(jīng)交由了Spring管理,在代碼中的體現(xiàn)就是類(lèi)上是否有@Service、Component等一系列注解。

解決方案:將Bean交由Spring進(jìn)行管理(添加@Service注解)

2.2 非public的方法進(jìn)行事務(wù)管理

默認(rèn)情況下你無(wú)法使用@Transactional對(duì)一個(gè)非public的方法進(jìn)行事務(wù)管理

解決方案:修改需要事務(wù)管理的方法為public

2.3 出現(xiàn)了自調(diào)用

多個(gè)方法都在同一個(gè)類(lèi)中,其中第一個(gè)方法中調(diào)用了本類(lèi)中的第二個(gè)和第三個(gè)方法,這就是自調(diào)用。

那么自調(diào)用為什么會(huì)導(dǎo)致事務(wù)失效呢?我們知道Spring中事務(wù)的實(shí)現(xiàn)是依賴于AOP的,當(dāng)容器在創(chuàng)建Service這個(gè)Bean時(shí),發(fā)現(xiàn)這個(gè)類(lèi)中存在了被@Transactional標(biāo)注的方法(修飾符為public)那么就需要為這個(gè)類(lèi)創(chuàng)建一個(gè)代理對(duì)象并放入到容器中。由于方法實(shí)際上是由Service也就是目標(biāo)類(lèi)自己調(diào)用的,所以在方法的前后并不會(huì)執(zhí)行事務(wù)的相關(guān)操作。這也是自調(diào)用帶來(lái)問(wèn)題的根本原因:自調(diào)用時(shí),調(diào)用的是目標(biāo)類(lèi)中的方法而不是代理類(lèi)中的方法。

解決方案

  • 自己注入自己,然后顯示的調(diào)用,
  • 這種方案看起來(lái)不是很優(yōu)雅
  • 利用AopContext,如下:
@Service
public class DemoService {
	@Transactional
	public void save(A a, B b) {
		((DemoService) AopContext.currentProxy()).saveB(b);
	}
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void saveB(B b){
		dao.saveB(a);
	}
}

使用上面這種解決方案需要注意的是,需要在配置類(lèi)上新增一個(gè)配置

// exposeProxy=true代表將代理類(lèi)放入到線程上下文中,默認(rèn)是false
@EnableAspectJAutoProxy(exposeProxy = true)

3. 事務(wù)回滾相關(guān)問(wèn)題

3.1 該回滾的時(shí)候事務(wù)提交了

這種情況往往是程序員對(duì)Spring中事務(wù)的rollbackFor屬性不夠了解導(dǎo)致的。

Spring默認(rèn)拋出了未檢查unchecked異常(繼承自 RuntimeException 的異常)或者 Error才回滾事務(wù);其他異常不會(huì)觸發(fā)回滾事務(wù),已經(jīng)執(zhí)行的SQL會(huì)提交掉。如果在事務(wù)中拋出其他類(lèi)型的異常,但卻期望 Spring 能夠回滾事務(wù),就需要指定rollbackFor屬性。

默認(rèn)情況下,只有出現(xiàn)RuntimeException或者Error才會(huì)回滾

public boolean rollbackOn(Throwable ex) {
? ? return (ex instanceof RuntimeException || ex instanceof Error);
}

所以,如果你想在出現(xiàn)了非RuntimeException或者Error時(shí)也回滾,請(qǐng)指定回滾時(shí)的異常,例如:

@Transactional(rollbackFor = Exception.class)

3.2 該提交的事務(wù)被回滾

對(duì)應(yīng)的異常信息如下:

Transaction rolled back because it has been marked as rollback-only

總結(jié)起來(lái),主要的原因就是因?yàn)閮?nèi)部事務(wù)回滾時(shí)將整個(gè)大事務(wù)做了一個(gè)rollbackOnly的標(biāo)記,所以即使我們?cè)谕獠渴聞?wù)中catch了拋出的異常,整個(gè)事務(wù)仍然無(wú)法正常提交,并且如果你希望正常提交,Spring還會(huì)拋出一個(gè)異常。

3.3 解決方案

這個(gè)解決方案要依賴業(yè)務(wù)而定,你要明確你想要的結(jié)果是什么

內(nèi)部事務(wù)發(fā)生異常,外部事務(wù)catch異常后,內(nèi)部事務(wù)自行回滾,不影響外部事務(wù)
將內(nèi)部事務(wù)的傳播級(jí)別設(shè)置為nested/requires_new均可。在我們的例子中就是做如下修改:

// @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
@Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
public void a() throws ClassNotFoundException{
    // ......
    throw new ClassNotFoundException();
}

雖然這兩者都能得到上面的結(jié)果,但是它們之間還是有不同的。當(dāng)傳播級(jí)別為requires_new時(shí),兩個(gè)事務(wù)完全沒(méi)有聯(lián)系,各自都有自己的事務(wù)管理機(jī)制(開(kāi)啟事務(wù)、關(guān)閉事務(wù)、回滾事務(wù))。但是傳播級(jí)別為nested時(shí),實(shí)際上只存在一個(gè)事務(wù),只是在調(diào)用a方法時(shí)設(shè)置了一個(gè)保存點(diǎn),當(dāng)a方法回滾時(shí),實(shí)際上是回滾到保存點(diǎn)上,并且當(dāng)外部事務(wù)提交時(shí),內(nèi)部事務(wù)才會(huì)提交,外部事務(wù)如果回滾,內(nèi)部事務(wù)會(huì)跟著回滾。

 內(nèi)部事務(wù)發(fā)生異常時(shí),外部事務(wù)catch異常后,內(nèi)外兩個(gè)事務(wù)都回滾,但是方法不拋出異常

4. 讀寫(xiě)分離跟事務(wù)結(jié)合使用時(shí)的問(wèn)題

讀寫(xiě)分離一般有兩種實(shí)現(xiàn)方式

  • 配置多數(shù)據(jù)源
  • 依賴中間件

如果是配置了多數(shù)據(jù)源的方式實(shí)現(xiàn)了讀寫(xiě)分離,那么需要注意的是:如果開(kāi)啟了一個(gè)讀寫(xiě)事務(wù),那么必須使用寫(xiě)節(jié)點(diǎn),如果是一個(gè)只讀事務(wù),那么可以使用讀節(jié)點(diǎn)。

如果是依賴于中間件那么需要注意:需要根據(jù)中間件的事務(wù)規(guī)范使用事務(wù)。

到此這篇關(guān)于spring事務(wù)@Transactional失效原因及解決辦法小結(jié)的文章就介紹到這了,更多相關(guān)spring @Transactional失效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論