SpringBoot2.x @Transactional 注意事项

在SpringBoot2.x中使用使用需要注意的地方:

  1. 加@Transactional的方法不能是private和protected修饰,private会直接报编译错误,protected不会报错,但是事务不起作用;
  2. @Transactional可以放在Controller下面直接起作用;
  3. @Transactional有两个包:import javax.transaction.Transactionalimport org.springframework.transaction.annotation.Transactional,这两个都可以用,对比他们两个的方法和属性,发现后面的比前面的强大,建议后后面的;
  4. PlatformTransactionManager这个接口中定义了三个方法 getTransaction创建事务commit 提交事务rollback 回滚事务,实现类是 AbstractPlatformTransactionManager;
  5. 在@Transactional这个中,有一个参数Propagation的属性,在它的七个类型中REQUIREDREQUIRES_NEW,NESTED,这三个都是新建事务,其他的都不使用事务;
  6. 当一个方法中嵌套使用@Transactional,如果没有设置属性 Propagation,默认为REQUIRED,只会在上下文创建一个事务,当设置属性为REQUIRES_NEW的时候,会创建一个新的事务;
  7. try&catch的使用,当一个事务中如果对异常进行了捕获,而且没有抛出异常的情况下,事务是不起作用的,只有抛出异常,事务会自己try&catch,然后进行回滚操作。
  8. @Transactional采用AOP实现,在调用方法时,发现这个方法有事务注解,AOP会检测到,然后用代理类采用反射机制进行调用:
    1. 首先调用了CglibAopProxy.intercept()方法
    2. 接下来调用ReflectiveMethodInvocation.proceed()方法
    3. TransactionInterceptor.invoke()
    4. TransactionAspectSupport.invokeWithinTransaction()
    5. TransactionAspectSupport.createTransactionIfNecessary()
    6. AbstractPlatformTransactionManager.getTransaction(),创建了一个新的事务。
  9. 问题注意:
    异常捕获在Controller去做,这样在Service层中 @Transactional在发生异常时可以正常进行回滚操作;
    如果使用Mysql数据库,需要注意创建表的引擎,支持InnoDD,默认创建表是 MyISAM;
    如果配置了自动创建,需要这样配置:
jpa:
  hibernate:
    ddl-auto: update
  show-sql: true
  database-platform: org.hibernate.dialect.MySQL5InnoDBDialect

一个栗子:
ServiceA.createTransaction()
SpringBoot2.x @Transactional 注意事项_第1张图片

参考:

https://www.cnblogs.com/baoyi/p/springboot_transactional.html
https://baike.baidu.com/item/JTA/9257852
https://www.oracle.com/technetwork/java/javaee/jta/index.html
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/annotation/Transactional.html

你可能感兴趣的:(Spring,Boot)