一、針對spring來說可以使用@transactional來開啟事務
二、常見Spring事務失效的場景:
1、注解@Transactional配置的方法非public權限修飾;
(1)、官方定義:使用代理時,您應該只將@Transactional注釋應用於具有公共可見性的方法。如果使用@Transactional注釋對受保護的、私有的或包可見的方法進行注釋,則不會引發錯誤,但帶注釋的方法不會顯示配置的事務設置。如果需要注釋非公共方法,請考慮使用AspectJ。
2、注解@Transactional所在類非Spring容器管理的bean;
(1)、非bean對象不能進行@transactional注解,無效。
3、注解@Transactional所在類中,注解修飾的方法被類內部方法調用;
(1)、在類A里面有方法a 和方法b,然后方法b上面用@Transactional加了方法級別的事務,在方法a里面 調用了方法b, 方法b里面的事務不會生效。
原理:Spring在掃描Bean的時候會自動為標注了@Transactional注解的類生成一個代理類(proxy),當有注解的方法被調用的時候,實際上是代理類調用的,代理類在調用之前會開啟事務,執行事務的操作。但是同一個類中的方法互相調用,相當於this.B(),此時的B方法並非是代理類調用,而是直接通過原有的Bean直接調用,所以注解會失效。
4、業務代碼拋出異常類型非RuntimeException,事務失效;
(1)、@Transactional注解修飾的方法,加上rollbackfor屬性值,指定回滾異常類型:@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)指定回滾異常類。
5、業務代碼中存在異常時,使用try…catch…語句塊捕獲,而catch語句塊沒有throw new RuntimeExecption異常;(最難被排查到問題且容易忽略)
(1)、解決方案:捕獲異常並拋出異常
6、注解@Transactional中Propagation屬性值設置錯誤即Propagation.NOT_SUPPORTED(一般不會設置此種傳播機制)
(1)、此種事務傳播行為不是特殊自定義設置,基本上不會使用Propagation.NOT_SUPPORTED,不支持事務
7、mysql關系型數據庫,且存儲引擎是MyISAM而非InnoDB,則事務會不起作用(基本開發中不會遇到);
(1)、以MySQL關系型數據為例,如果其存儲引擎設置為 MyISAM,則事務失效,因為MyISMA 引擎是不支持事務操作的;
故若要事務生效,則需要設置存儲引擎為InnoDB ;目前 MySQL 從5.5.5版本開始默認存儲引擎是:InnoDB。
