2023-07-05 13:24:23來源:JAVA日知錄
這里以 MySQL為例,MyISAM引擎是不支持事務(wù)操作的,一般要支持事務(wù)都會使用InnoDB引擎,根據(jù)MySQL 的官方文檔說明,從MySQL 5.5.5 開始的默認(rèn)存儲引擎是 InnoDB,之前默認(rèn)的都是 MyISAM,所以這一點(diǎn)要值得注意,如果底層引擎不支持事務(wù),那么再怎么設(shè)置也沒有用。
2.沒有被 Spring 管理示例如下:
(資料圖片僅供參考)
public class OrderServiceImpl implements OrderService{ @Transactional public void updateOrder(Order order){ //update order }}
如果此時把@Service注解注釋掉,那么這個類就不會被加載成一個Bean,這個類就不會Spring管理了,事務(wù)自然就失效了。
3. 方法不是 public 的@Transactional注解只能用干public 的方法上,否則事多不會生效,如果要用在非public的方法上,則可以開啟基于 AspcetJ 框架的靜態(tài)代理模式。
4.發(fā)生自身調(diào)用示例如下:
@Servicepublic class OrderServiceImpl implements OrderService { public void update(Order order) { updateOrder(order); }}@Transactionalpublic void updateOrder(0rder order) { // update order }}
update 方法上面沒有加@Transactional注解,如果調(diào)用有@Transactional注解的updateOrder 方法,那么 updateOrder 方法上的事務(wù)還可以生效嗎? 這里大家可以先想一想,后面會揭曉答案。
再來看下面這個例子:
@Servicepublic class OrderServiceImpl implements OrderService { @Transactional public void update(Order order) { updateOrder(order); }}@Transactional(propagation = Propagation.REQUIRES_NEW)public void updateOrder(0rder order) { updateOrder(order); }}
這次在 update 方法上加了@Transactional, 如果在 updateOrder 上加了REOUIRES_NEW新開啟一個事務(wù),那么新開啟的事務(wù)可以生效嗎?
這兩個例子中的事務(wù)都不會生效,因?yàn)樗鼈儼l(fā)生了自身調(diào)用,就調(diào)用了該類自己的方法,而沒有經(jīng)過Spring的代理類,默認(rèn)只有調(diào)用外部代理類的方法,事務(wù)才會生效,這也是老生常談的問題了。
這個問題的解決方案之一就是在事務(wù)所在的類中注入自己,用往入的對象再調(diào)用另外一個方法,這個不太優(yōu)雅,在Spring 中可以在當(dāng)前線程中暴露并獲取當(dāng)前代理類,通過在啟動類上添加以下注解來啟用暴露代理類,如下面的示例所示。
@EnableAspectJAutoProxy(exposeProxy = true)
然后通過以下代碼獲取當(dāng)前代理類,并調(diào)用代理類的事務(wù)方法:
((0rderService) AopContext.currentProxy()).updateOrder();
Spring 默認(rèn)只有調(diào)用 Spring代理類的public 方法,事務(wù)才能生效。
5.沒有配置事務(wù)管理器如果沒有配置以下DataSourceTransactionManager數(shù)據(jù)源事務(wù)管理器,那么事務(wù)也不會生效 :
@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource);}
但在 Spring Boot 中只要引入了spring-boot-starter-data-jdbc啟動器依賴就會自動配置DataSourceTransactionManager數(shù)據(jù)源事務(wù)管理器,所以 Spring Boot框架不存在這個問題,但在傳統(tǒng)的 Spring 框架中需要注意。
6. 設(shè)置了不支持事務(wù)示例如下:
@Servicepublic class OrderServiceImpl implements OrderService { @Transactional public void update(Order order) { updateOrder(order); } @Transactional(propagation = Propagation.NOT_SUPPORTED) public void updateOrder(Order order) { //update order }}
這里的Propagation.NOT_SUPPORTED表示當(dāng)前方法不以事務(wù)方式運(yùn)行,當(dāng)前若存在事務(wù)則掛起,這就是主動不支持以事務(wù)方式運(yùn)行了。
7. 異常沒有被拋出示例如下:
@Servicepublic class OrderServiceImpl implements OrderService { @Transactional public void update(Order order) { try{ // update order }catch{ } }}
這個方法把異常給捕獲了,但沒有拋出來,所以事務(wù)不會回滾,只有捕捉到異常事務(wù)才會生效。
8. 異常類型不匹配示例如下:
@Servicepublic class OrderServiceImpl implements OrderService { @Transactional public void update(Order order) { try{ // update order }catch{ throw new Exception("更新失敗"); } }}
因?yàn)?Spring 默認(rèn)回滾的是 RuntimeException 異常,和程序拋出的 Exception 異常不匹配,所以事務(wù)也是不生效的。如果要觸發(fā)默認(rèn) RuntimeException之外異常的回滾,則需要在 @Transactiona事務(wù)注解上指定異常類,示例如下:
@Transactional(rollbackFor = Exception.class)
在今天的文章中總結(jié)了使用 @Transactional注解導(dǎo)致事務(wù)失效的幾個常見場景,如果 @Transactional事務(wù)不生效,則可以根據(jù)這幾種情形排查一下,其實(shí)次數(shù)最多的也就是發(fā)生自身調(diào)用、異常被捕獲、異常拋出類型不匹配這幾種場景。
關(guān)鍵詞:
1 數(shù)據(jù)庫引擎不支持事務(wù)這里以MySQL為例,MyISAM引擎是不支持事務(wù)操作
隨著前端項目的不斷迭代,就可能出現(xiàn)部分CSS代碼未使用的情況。這些未
物聯(lián)網(wǎng)為企業(yè)提供了更高的可見性、自動化和運(yùn)營效率。已經(jīng)開始研究部署
7月5日消息,GitHub和NPM的前工程經(jīng)理DarcyClarke上周警告稱,NPM包存
雖然連接設(shè)備是物聯(lián)網(wǎng)數(shù)據(jù)的關(guān)鍵來源,但其全部價值將在可互操作的物聯(lián)
太平洋保利盈2 0兩全保險怎么樣?滿期能領(lǐng)多少錢?適合什么人買?太平
在WWDC2023主題演講中,蘋果非常關(guān)注游戲,更具體地說,是Mac上的游戲
注解的高級使用自定義注解是Java語言的一項特性,可以為程序元素(類、
哈嘍,大家好,我是了不起。如題,這個問題應(yīng)該面試??碱},當(dāng)你遇到這
flag包作用Golang中的flag包用于解析命令行參數(shù),提供了一個方便的接口
一、背景1 1什么是精細(xì)化運(yùn)營?用戶畫像:注重用戶細(xì)分,深入分析用戶
隨著大模型的發(fā)展,尤其是近來各種開源大模型的發(fā)布,如何對各種模型進(jìn)
博德之門3怎么增加暴擊率的問題原因是什么?博德之門3是一款非常熱門的
綾致時裝Bestseller1975年始建于丹麥,創(chuàng)始人為TroelsHolchPovlsen。Bestseller
江粉兒從內(nèi)江華潤燃?xì)夥?wù)號獲悉,內(nèi)江城區(qū)這些區(qū)域?qū)⑼猓斍槿缦隆?/p>