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

聊聊spring @Transactional 事務(wù)無(wú)法使用的可能原因

 更新時(shí)間:2021年07月17日 11:50:04   作者:居十四  
這篇文章主要介紹了spring @Transactional 事務(wù)無(wú)法使用的可能原因,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

spring transaction

建議

Spring團(tuán)隊(duì)的建議是你在具體的類(lèi)(或類(lèi)的方法)上使用 @Transactional 注解,

而不要使用在類(lèi)所要實(shí)現(xiàn)的任何接口上。你當(dāng)然可以在接口上使用 @Transactional 注解,

但是這將只能當(dāng)你設(shè)置了基于接口的代理時(shí)它才生效。

因?yàn)樽⒔馐遣荒芾^承的,

這就意味著如果你正在使用基于類(lèi)的代理時(shí),那么事務(wù)的設(shè)置將不能被基于類(lèi)的代理所識(shí)別,

而且對(duì)象也將不會(huì)被事務(wù)代理所包裝(將被確認(rèn)為嚴(yán)重的)。

因此請(qǐng)接受Spring團(tuán)隊(duì)的建議并且在具體的類(lèi)上使用 @Transactional 注解。

事務(wù)無(wú)法使用的可能原因

導(dǎo)入spring的事務(wù)注解

應(yīng)該是

org.springframework.transaction.annotation.Transactional

而不是

javax.transaction.Transactional

是否開(kāi)啟了對(duì)注解的解析:

xml 文件配置

<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

springboot

注解開(kāi)啟自動(dòng)掃描

@EnableTransactionManagement

spring是否掃描到你使用注解事務(wù)的這個(gè)類(lèi)所在的包

配置xml

<context:component-scan base-package="com.xxx.xxx" ></context:component-scan>

springboot 開(kāi)啟事務(wù)

@EnableTransactionManagement

數(shù)據(jù)庫(kù)引擎要支持事務(wù)

如果是mysql,注意表要使用支持事務(wù)的引擎,比如InnoDB,如果是myisam,事務(wù)是不起作用的

springboot的配置

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

檢查方法是不是public的

@Transactional 僅僅在 public 方法,才能進(jìn)行事務(wù)管理。

photo_1

這是因?yàn)樵谑褂?Spring AOP 代理時(shí),

Spring 在調(diào)用在圖中的 TransactionInterceptor 在目標(biāo)方法執(zhí)行前后進(jìn)行攔截之前(圖中是cglib代理)

DynamicAdvisedInterceptor(CglibAopProxy 的內(nèi)部類(lèi))的的 intercept 方法或 JdkDynamicAopProxy 的 invoke 方法會(huì)間接調(diào)用 AbstractFallbackTransactionAttributeSource ,而會(huì)去調(diào)用computeTransactionAttribute 方法。

protected TransactionAttribute computeTransactionAttribute(Method method,
    Class<?> targetClass) {
        // Don't allow no-public methods as required.
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
   return null;
  }
 }

這個(gè)方法會(huì)判斷如果不是 public 則會(huì)返回 null

異常類(lèi)型是不是unchecked異常

默認(rèn),只有unchecked異常時(shí)才回滾該事務(wù)

spring只有在拋出的異常為運(yùn)行時(shí)unchecked異常時(shí)才回滾該事務(wù),

也就是拋出的異常為RuntimeException的子類(lèi)(Errors也會(huì)導(dǎo)致事務(wù)回滾).

而拋出checked異常則不會(huì)導(dǎo)致事務(wù)回滾??梢悦鞔_的配置在拋出那些異常時(shí)回滾事務(wù),

包括checked異常。也可以明確定義那些異常拋出時(shí)不回滾事務(wù)。

如果想讓checked異常也回滾,在注解上面寫(xiě)明異常類(lèi)型即可:

@Transactional (rollbackFor=Exception.class)

noRollbackFor 自定義不回滾的異常

異常是不是被catch住了

Service層捕捉異常后,發(fā)現(xiàn)事務(wù)不生效。

Service層手工捕捉并處理了異常(try…catch)等于把異常吃掉了,

Spring自然不知道這里有錯(cuò),更不會(huì)主動(dòng)去回滾數(shù)據(jù)。推薦做法是在Service層統(tǒng)一拋出異常,

然后在Controll層統(tǒng)一處理。

下面代碼事務(wù)是無(wú)法生效的

//在類(lèi)上@Transactional 說(shuō)明,所以public都是有事務(wù)的
@Service
@Transactional
public class StudentService {

	@Autowired
	private GroupRepository groupRepository;
	@Autowired
	private InstituteRepository instituteRepository;

	public void initStudent() {
		Institute institute = Institute.builder().build();
		institute.setCode("TEST4");
		instituteRepository.save(institute);
		
		// 這里自己處理異常,spring不會(huì)知道存在異常,無(wú)法進(jìn)行事務(wù)回滾
		try {
			throw new RuntimeException("運(yùn)行時(shí)異常----------看事務(wù)是否起作用");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}

修改成如下代碼

public void initStudent() throws Exception{
  Institute institute = Institute.builder().build();
  institute.setCode("TEST4");
  instituteRepository.save(institute);
  groupRepository.save(group);
  
  //不進(jìn)行異常處理,而是把異常拋出
  throw new RuntimeException("運(yùn)行時(shí)異常----------看事務(wù)是否起作用");
 }

避免 Spring 的 AOP 的自調(diào)用問(wèn)題

檢查是不是同一個(gè)類(lèi)中的方法調(diào)用(如a方法調(diào)用同一個(gè)類(lèi)中的b方法),從而避免 Spring AOP 的自調(diào)用問(wèn)題

這是因?yàn)樵?Spring AOP 代理下,只有目標(biāo)方法由外部調(diào)用,

目標(biāo)方法才由 Spring 生成的代理對(duì)象來(lái)管理,這會(huì)造成自調(diào)用問(wèn)題。

若同一類(lèi)中的其他沒(méi)有@Transactional 注解的方法內(nèi)部調(diào)用有@Transactional 注解的方法,

@Transactional 注解的方法的事務(wù)被忽略,不會(huì)發(fā)生回滾。

@Service
public class StudentService {

 @Autowired
 private GroupRepository groupRepository;
 @Autowired
 private InstituteRepository instituteRepository;
 
 //initStudent() 加上@Transactional(),則會(huì)回滾
 public void initStudent() throws Exception{
  Institute institute = Institute.builder().build();
  institute.setCode("TEST4");
  instituteRepository.save(institute);
  
  //雖然 initGroup() 有 @Transactional() 但是事務(wù)還是沒(méi)起作用
  initGroup();
  throw new RuntimeException("運(yùn)行時(shí)異常----------看事務(wù)是否起作用");
 }
 
 @Transactional()
 public void initGroup() {
  Group group = Group.builder().academic_year(2015).build();
  group.setCode("ELSE1");
  groupRepository.save(group);
 }
}

AspectJ 取代 Spring AOP 代理

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java重載構(gòu)造原理與用法詳解

    Java重載構(gòu)造原理與用法詳解

    這篇文章主要介紹了Java重載構(gòu)造原理與用法,結(jié)合實(shí)例形式分析了java可變參數(shù)、方法重載、構(gòu)造器等相關(guān)概念、原理及操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • SpringCloud實(shí)現(xiàn)服務(wù)調(diào)用feign與熔斷hystrix和網(wǎng)關(guān)gateway詳細(xì)分析

    SpringCloud實(shí)現(xiàn)服務(wù)調(diào)用feign與熔斷hystrix和網(wǎng)關(guān)gateway詳細(xì)分析

    這篇文章主要介紹了SpringCloud實(shí)現(xiàn)服務(wù)調(diào)用feign與熔斷hystrix和網(wǎng)關(guān)gateway,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-04-04
  • Java框架之Maven SSM集合

    Java框架之Maven SSM集合

    本篇文章主要介紹了基于maven的ssm框架整合的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-09-09
  • Java學(xué)習(xí)之緩沖流的原理詳解

    Java學(xué)習(xí)之緩沖流的原理詳解

    為了提高其數(shù)據(jù)的讀寫(xiě)效率,Java中又定義了四種緩沖流,分別是:字節(jié)緩沖輸入流、字節(jié)緩沖輸出流、字符緩沖輸入流和字符緩沖輸出流。本文主要來(lái)和大家聊聊這些緩沖流的原理,希望對(duì)大家有所幫助
    2023-01-01
  • java.util.Collection源碼分析與深度理解

    java.util.Collection源碼分析與深度理解

    這篇文章主要給大家介紹了關(guān)于java.util.Collection的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java List集合方法及遍歷過(guò)程代碼解析

    Java List集合方法及遍歷過(guò)程代碼解析

    這篇文章主要介紹了Java List集合方法及遍歷過(guò)程代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • AsyncConfigurerSupport自定義異步線(xiàn)程池處理異常

    AsyncConfigurerSupport自定義異步線(xiàn)程池處理異常

    這篇文章主要為大家介紹了AsyncConfigurerSupport自定義異步線(xiàn)程池處理異常詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 深入解析Apache Kafka實(shí)時(shí)流處理平臺(tái)

    深入解析Apache Kafka實(shí)時(shí)流處理平臺(tái)

    這篇文章主要為大家介紹了Apache Kafka實(shí)時(shí)流處理平臺(tái)深入解析,從基本概念到實(shí)戰(zhàn)操作詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Java 如何快速,優(yōu)雅的實(shí)現(xiàn)導(dǎo)出Excel

    Java 如何快速,優(yōu)雅的實(shí)現(xiàn)導(dǎo)出Excel

    這篇文章主要介紹了Java 如何快速,優(yōu)雅的實(shí)現(xiàn)導(dǎo)出Excel,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-03-03
  • Java發(fā)送http請(qǐng)求的示例(get與post方法請(qǐng)求)

    Java發(fā)送http請(qǐng)求的示例(get與post方法請(qǐng)求)

    這篇文章主要介紹了Java發(fā)送http請(qǐng)求的示例(get與post方法請(qǐng)求),幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01

最新評(píng)論