快捷搜索: 王者荣耀 脱发

事务注解与全局事务配置

事务配置

0、前言

 近期,我在项目中使用事务注解(@Transactional)的时候发现一个问题:事务失效。

/**
 * 事务回滚失败
 * example1 还是保存了
 */
@Transactional
public void saveEntity(ExampleVo exampleVo) {
          
   
 	 Example1 example1 = exampleVo.getExample1();
     example1Dao.save(example1);
	
     // throw ArithmeticException
     int res = 10/0;
     
     Example2 example2 = exampleVo.getExample2();
     example2Dao.save(example2);
 }

排查:

    @Transactional 排查,rollbackFor 属性默认为 RuntimeException 和 Error,ArithmeticException 继承于 RuntimeException,没有发现问题原因; 添加全局事务配置,没有发现问题原因; 数据库排查,发现问题原因,数据库表所使用的存储引擎为 MyISAM,MyISAM 不支持事务。将数据库表的存储引擎改为 InnoDB 后,问题解决。
// 显示数据库表所使用的存储引擎 
show create table example1;

// 修改存储引擎
alter table example1 engine = InnoDB;

问题产生的原因:

 该项目使用的持久化框架为 JPA,同时数据库表由 JPA 自动生成,而由 JPA 自动生成的表若无配置表的存储引擎,JPA 默认采用 MyISAM 作为表的存储引擎。

spring:
  jpa:
    hibernate:
      dialect: org.hibernate.dialect.MySQL5Dialect

1、事务注解

 @Transactional 开启事务,可以标注在类或方法上。

官方注释:Describes a transaction attribute on an individual method or on a class.

比较重要的属性:

    propagation:传播类型,默认 Propagation.REQUIRED ; isolation:隔离级别,默认 Isolation.DEFAULT(采用数据库的默认隔离级别); rollbackFor:触发事务回滚的异常类型,默认为 RuntimeException 和 Error 。

2、全局事务配置

2.1、启动类

@SpringBootApplication
@EnableTransactionManagement
public class MessageApplication {
          
   
    public static void main(String[] args) {
          
   
        SpringApplication.run(MessageApplication.class, args);
    }
}

2.2、配置类


3、AOP 补充

切入点表达式语法:

execution( [访问控制权限修饰符] 返回值类型 [全限定类名] 方法名(形式参数列表) [异常] )
    访问控制权限修饰符:可选项,默认任意类型; 返回值类型:必选项,* 表示任意类型; 全限定类名:可选项,… 表示当前包以及子包下的所有类,默认所有类; 方法名:必选项,* 表示任意方法; 形式参数列表,必选项,() 表示没有参数的方法,(…) 表示参数类型和个数任意的方法,(, String) 表示第一个参数类型任意,第二个参数类型为 String 。
/** 
 *  表示
 *    任意访问控制权限修饰符 
 *  * 任意返回值 
 *  com.example.message.service.. com.example.message.service 包及其子包下的
 *  *. 所有类下的
 *  * 任意方法
 *  (..) 形式参数列表任意 
 */
execution(* com.example.message.service..*.*(..))
经验分享 程序员 微信小程序 职场和发展